#ifndef _SYS_USW_NEXTHOP_H_
#define _SYS_USW_NEXTHOP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "sal.h"
#include "ctc_const.h"
#include "ctc_avl_tree.h"
#include "ctc_aps.h"
#include "ctc_vector.h"
#include "ctc_spool.h"
#include "ctc_debug.h"
#include "ctc_vlan.h"
#include "ctc_nexthop.h"
#include "ctc_stats.h"
#include "drv_api.h"
#include "sys_usw_nexthop_api.h"

/*  if nsh spec is 8 and escl entry num is 16,
    then edit_offset, hw_index and bus_offset mapping table as following:
    --------------------------------------------------
    | edit_offset | 0 | 1 | 2 | 3 | 4  | 5 | 6  | 7  |
    --------------------------------------------------
    | hw_index    | 0 | 1 | 4 | 5 | 8  | 9 | 12 | 13 |
    --------------------------------------------------
    | bus_offset  | 4 | 1 | 8 | 5 | 12 | 9 | 16 | 13 |
    --------------------------------------------------
*/
#define SYS_NH_NSH_EDIT_OFFSET_MAP(logic_index)  ((logic_index<<1)-(logic_index&1))
#define SYS_NH_NSH_EDIT_OFFSET_UNMAP(hw_index)   ((hw_index+(hw_index&1))>>1)
#define SYS_NH_NSH_EDIT_TBL(lchip, tbl_id)  \
do {\
    drv_ftm_info_detail_t ftm_info;\
    ftm_info.info_type = DRV_FTM_INFO_TYPE_MAX;\
    CTC_ERROR_RETURN(drv_usw_ftm_get_info_detail(lchip, &ftm_info));\
    (tbl_id) = CTC_IS_BIT_SET(ftm_info.nsh_mode, 0) ? DsNshEdit1_t : DsNshEdit0_t;\
}while(0)

#define SYS_NH_INIT_CHECK \
    do { \
		 if ((lchip) >= CTC_MAX_LOCAL_CHIP_NUM_PP){  \
            SYS_NH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid Local chip id \n");\
			return CTC_E_INVALID_CHIP_ID;\
 }\
        if (!p_usw_nh_api_master[lchip]){ SYS_NH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " Feature not initialized \n");\
			return CTC_E_NOT_INIT;\
 } \
    } while (0)

#define SYS_PP_IS_REMOTE(lchip, dest_pp) 1

#define SYS_NH_MCAST_REPLI_INCR_STEP   4
#define SYS_NH_LOGICAL_REPLI_MAX_NUM   32
#define SYS_NH_LOGICAL_REPLI_NUM 16
#define SYS_NH_EXTERNAL_NHID_MAX_BLK_NUM     16
#define SYS_NH_INTERNAL_NHID_MAX_BLK_NUM     16
#define SYS_NH_INTERNAL_NHID_BLK_SIZE        2048
#define SYS_NH_INTERNAL_NHID_MAX \
    ((g_usw_nh_master[lchip]->max_external_nhid) + (SYS_NH_INTERNAL_NHID_MAX_BLK_NUM * SYS_NH_INTERNAL_NHID_BLK_SIZE))

#define SYS_NH_INTERNAL_NHID_MAX_SIZE  (0xFFFFFFFF-0x80000000)
#define SYS_NH_NHID_HASH_SIZE  32768

#define SYS_DSNH_DESTVLANPTR_SPECIAL 0
#define SYS_NH_ROUTED_PORT_VID    0xFFF

#define SYS_NH_TUNNEL_ID_MAX_BLK_NUM     16
#define SYS_NH_MCAST_GROUP_MAX_BLK_SIZE     256
#define SYS_NH_MCAST_MEMBER_BITMAP_SIZE     64

#define SYS_NH_DSNH_OFFSET_MODEROUTED_PORT_VID    0xFFF
#define SYS_NH_INTERNAL_NHID_OL_VNI_BASE          0xa0000000

#define SYS_NH_CW_NUM    16
#define SYS_NH_PON_MC_DSNH_NUM 2
#define SYS_NH_FP_NUM 4096

#define SYS_NH_IP_TUNNEL_IS_OVERLAY_TUNNEL(p_param)                     \
    ((CTC_TUNNEL_TYPE_NVGRE_IN4 == p_param->tunnel_info.tunnel_type)    \
     ||(CTC_TUNNEL_TYPE_NVGRE_IN6 == p_param->tunnel_info.tunnel_type)  \
     ||(CTC_TUNNEL_TYPE_VXLAN_IN4 == p_param->tunnel_info.tunnel_type)  \
     ||(CTC_TUNNEL_TYPE_VXLAN_IN6 == p_param->tunnel_info.tunnel_type)  \
     ||(CTC_TUNNEL_TYPE_GENEVE_IN4 == p_param->tunnel_info.tunnel_type)  \
     ||(CTC_TUNNEL_TYPE_GENEVE_IN6 == p_param->tunnel_info.tunnel_type))


#define SYS_NH_DSNH_INTERNAL_BASE (g_usw_nh_master[lchip]->internal_nexthop_base)
#define SYS_NH_DSNH_INTERNAL_SHIFT   4
#define SYS_NH_BUILD_INT_OFFSET(offset) \
    (SYS_NH_DSNH_INTERNAL_BASE<<SYS_NH_DSNH_INTERNAL_SHIFT)|offset;

#define SYS_DSNH4WREG_INDEX_FOR_BPE_TRANSPARENT   0x0      /*must 0,1 use dsnexthop8w for bpe ecid tranparent*/
#define SYS_DSNH4WREG_INDEX_FOR_BRG            0xC      /*must be b1100, for GB is b00, shift is 2*/
#define SYS_DSNH4WREG_INDEX_FOR_MIRROR         0xD      /*must be b1101, for GB is b01, shift is 2*/
#define SYS_DSNH4WREG_INDEX_FOR_BYPASS         0xE      /*must be b1110, for GB is b10, shift is 2, (use 8w)*/
#define SYS_DSNH4WREG_INDEX_FOR_WLAN_DECAP     0x2      /*reserve for wlan decap internal used*/
#define SYS_DSNH4WREG_INDEX_FOR_OL_BRG     0x3      /*reserve for overlay bridge nh*/
#define SYS_DSNH4WREG_INDEX_FOR_TWAMP_UPD_CHKSUM   0x4      /*reserve for twamp sender update udp checksum*/
#define SYS_DSNH4WREG_INDEX_FOR_STK_IGS_EDT     0x6      /*reserve for overlay bridge nh*/

#define SYS_DSNH_INDEX_FOR_REMOTE_MIRROR  0  /*must be 0, Only Used for compatible for GG Ingress Edit Mode,
                                                  for D2 not need reserve remote mirror nexthop ptr*/
#define SYS_DSNH_INDEX_FOR_NONE 1               /*Reserved for doing nothing*/

#define SYS_NH_L2EDIT_HASH_BLOCK_SIZE  16
#define SYS_NH_L2EDIT_HASH_BLOCK_NUM (1024/SYS_NH_L2EDIT_HASH_BLOCK_SIZE)


#define SYS_NH_MPLS_LABEL_EXP_SELECT_PACKET  0
#define SYS_NH_MPLS_LABEL_EXP_SELECT_MAP     1
#define SYS_NH_MAX_EXP_VALUE                 7

#define SYS_NH_IP_TUNNEL_IPV6_PROTO_TYPE 41
#define SYS_NH_IP_TUNNEL_IPV4_PROTO_TYPE 4

#define SYS_NH_ECMP_RESEVED_NUM 4  /*rsv for drop*/
#define SYS_ECMP_MEM_HW_SUB_NUM 4

#define SYS_NH_CHECK_MPLS_EXP_VALUE(exp)                    \
    do {                                                        \
        if ((exp) > (7)){return CTC_E_INVALID_PARAM; }         \
    } while (0);

#define SYS_NH_CHECK_MPLS_LABVEL_VALUE(label)               \
    {                                                        \
        if ((label) > (0xFFFFF)){                                 \
            return CTC_E_INVALID_PARAM; }              \
    }

#define SYS_NH_CHECK_MPLS_EXP_TYPE_VALUE(type)                    \
    do {                                                        \
        if ((type) >= (MAX_CTC_NH_EXP_SELECT_MODE)){return CTC_E_INVALID_PARAM; }         \
    } while (0);

#define GPORT_TO_INDEX(gport)  \
    ((SYS_MAP_CTC_GPORT_TO_GCHIP(gport) == 0x1f) ? \
    (MCHIP_CAP(SYS_CAP_NEXTHOP_PORT_NUM_PER_CHIP) * MCHIP_CAP(SYS_CAP_NEXTHOP_MAX_CHIP_NUM) + SYS_MAP_CTC_GPORT_TO_DRV_LPORT(gport)) : \
    (SYS_MAP_CTC_GPORT_TO_GCHIP(gport) * MCHIP_CAP(SYS_CAP_NEXTHOP_PORT_NUM_PER_CHIP) + SYS_MAP_CTC_GPORT_TO_DRV_LPORT(gport)))


#define SYS_NH_DSFWD_CHK(nh_entry_flags, is_dsfwd1)\
    do { \
           if (CTC_FLAG_ISSET(nh_entry_flags, SYS_NH_INFO_FLAG_HAVE_DSFWD) && (0 == is_dsfwd1))\
           {return CTC_E_NONE;}\
           if (DRV_FROM_AT(lchip) && CTC_FLAG_ISSET(nh_entry_flags, SYS_NH_INFO_FLAG_HAVE_DSFWD1) && (1 == is_dsfwd1))\
           {return CTC_E_NONE;}\
    } while (0)

#define SYS_NH_GEMPORT_MAP(ldp) \
    (g_usw_nh_master[lchip]->gem_port_edit_num ?  ((ldp >> 3)*2 + g_usw_nh_master[lchip]->gem_port_edit_base): \
                                       ((ldp >> 3)*2 + (DRV_FROM_TMM(lchip)? 2 : 0))) /*Map logicport to gemport editptr*/

#define SYS_ECMP_MAX_HECMP_MEM  7
#define SYS_NH_MAP_UNIT_SIZE 24
#define SYS_NH_DEST_PP_NONE 0xFF
#define SYS_NH_DEST_PP_ALL  0xFE

#define SYS_MET_VEC_SLIM_1X   0  /* met_ext_mode != 0, port 0~63, use DsMetVectorSlim1X */
#define SYS_MET_VEC_SLIM_2X_0 1  /* met_ext_mode != 0, port 64~127, use DsMetVectorSlim2X(high 64bits), bmpShiftType = 0 */
#define SYS_MET_VEC_SLIM_2X_1 2  /* met_ext_mode != 0, port 128~255, use DsMetVectorSlim2X, bmpShiftType = 1 */
#define SYS_MET_VEC_SLIM_2X_2 3  /* met_ext_mode != 0, port 256~383, use DsMetVectorSlim2X, bmpShiftType = 2 */
#define SYS_MET_VEC_SLIM_2X_3 4  /* met_ext_mode != 0, port 384~511, use DsMetVectorSlim2X, bmpShiftType = 3 */

#define SYS_MET_VEC_2X_PORT_BASE 384

#define SYS_MAX_DS_0_SIZE 20
typedef uint32 ds0_t[SYS_MAX_DS_0_SIZE];

#define SYS_NH_MET_END_REPLICATE_OFFSET  ((DRV_FROM_AT(lchip)&&g_usw_nh_master[lchip]->met_ext_mode)?0xFFFFF:0xFFFF)/*AT met ext mode, nextMetEntryPtr is 20bits*/
#define SYS_NH_PHY_REP_MAX_NUM             (DRV_FROM_AT(lchip)?0x1FFF:0xFFF)

#define SYS_MET_MODE_NORMAL  0 /*normal mode*/
#define SYS_MET_MODE_EXT     1 /*ext mode*/


struct sys_hbnh_brguc_node_info_s
{
    uint32 gport;
    uint32 nhid_brguc;
    uint32 nhid_bypass;

};
typedef struct sys_hbnh_brguc_node_info_s sys_hbnh_brguc_node_info_t;

struct sys_usw_brguc_info_s
{
    ctc_hash_t*   brguc_hash;    /*Maintains ucast bridge DB(no egress vlan trans)*/
    sal_mutex_t*  brguc_mutex;
    #ifdef WARMBOOT
    uint32        rchip_nh_cnt;
    #endif
};
typedef struct sys_usw_brguc_info_s sys_usw_brguc_info_t;

struct sys_nh_eloop_node_s
{
    ctc_slistnode_t head;
    uint32 nhid;   /*nhid and edit_ptr are 1:1*/
    uint32 edit_ptr;
    uint8 is_l2edit;
    uint8 lb_with_ldp;
    uint16 ref_cnt;
};
typedef struct sys_nh_eloop_node_s sys_nh_eloop_node_t;

struct sys_usw_nh_api_master_s
{
    sys_usw_brguc_info_t brguc_info;
    sal_mutex_t*  p_mutex;
};
typedef struct sys_usw_nh_api_master_s sys_usw_nh_api_master_t;

enum sys_nh_entry_pld_op_type_e
{
    SYS_NH_OP_NONE = 0,
    SYS_NH_OP_ROUTE,
    SYS_NH_OP_BRIDGE,
    SYS_NH_OP_BRIDGE_VPLS,             /* BRIDGE_VPLS_VC for SGMAC */
    SYS_NH_OP_BRIDGE_INNER,
    SYS_NH_OP_MIRROR,
    SYS_NH_OP_ROUTE_NOTTL,
    SYS_NH_OP_ROUTE_COMPACT   /*L2Edit merge to Nexthop ipuc/ipmc*/
};
typedef enum sys_nh_entry_pld_op_type_e sys_nh_entry_pld_op_type_t;

enum sys_nh_entry_share_type_e
{
    SYS_NH_SHARE_TYPE_L23EDIT = 0,
    SYS_NH_SHARE_TYPE_VLANTAG = 1,
    SYS_NH_SHARE_TYPE_L2EDIT_VLAN = 2,
    SYS_NH_SHARE_TYPE_SPAN_PACKET = 3,
    SYS_NH_SHARE_TYPE_MAC_DA = 4,
};
typedef enum sys_nh_entry_share_type_e sys_nh_entry_share_type_t;

enum sys_nh_l3edit_tunnelv4_share_type_e
{
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_NULL = 0,
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_GRE,
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_6RD,
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_6TO4,
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_NVGRE,
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_VXLAN,
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_WLAN,
    SYS_NH_L3EDIT_TUNNELV4_SHARE_TYPE_NAT64
};
typedef enum sys_nh_l3edit_tunnelv4_share_type_e sys_nh_l3edit_tunnelv4_share_type_t;

enum sys_nh_l3edit_tunnelv6_share_type_e
{
    SYS_NH_L3EDIT_TUNNELV6_SHARE_TYPE_NULL = 0,
    SYS_NH_L3EDIT_TUNNELV6_SHARE_TYPE_GRE,
    SYS_NH_L3EDIT_TUNNELV6_SHARE_TYPE_NORMAL,
    SYS_NH_L3EDIT_TUNNELV6_SHARE_TYPE_NVGRE,
    SYS_NH_L3EDIT_TUNNELV6_SHARE_TYPE_VXLAN,
    SYS_NH_L3EDIT_TUNNELV6_SHARE_TYPE_WLAN,
    SYS_NH_L3EDIT_TUNNELV6_SHARE_TYPE_NAT46
};
typedef enum sys_nh_l3edit_tunnelv6_share_type_e sys_nh_l3edit_tunnelv6_share_type_t;

enum sys_nh_entry_l2edit_type_e
{
    SYS_NH_L2EDIT_TYPE_NONE =0,
    SYS_NH_L2EDIT_TYPE_LOOPBACK,
    SYS_NH_L2EDIT_TYPE_ETH_4W,
    SYS_NH_L2EDIT_TYPE_ETH_8W,
    SYS_NH_L2EDIT_TYPE_MAC_SWAP,
    SYS_NH_L2EDIT_TYPE_FLEX_8W,
    SYS_NH_L2EDIT_TYPE_PBB_4W,
    SYS_NH_L2EDIT_TYPE_PBB_8W,
    SYS_NH_L2EDIT_TYPE_OF,
    SYS_NH_L2EDIT_TYPE_INNER_SWAP,
    SYS_NH_L2EDIT_TYPE_INNNER_DS_LITE,
    SYS_NH_L2EDIT_TYPE_INNNER_DS_LITE_8W,
    SYS_NH_L2EDIT_TYPE_INVALID,

    SYS_NH_L2EDIT_TYPE_MAX
};
typedef enum sys_nh_entry_l2edit_type_e sys_nh_entry_l2edit_type_t;


enum sys_nh_l2_edit_extra_header_type_e
{
    SYS_L2EDIT_EXTRA_HEADER_TYPE_NONE = 0,
    SYS_L2EDIT_EXTRA_HEADER_TYPE_ETHERNET,
    SYS_L2EDIT_EXTRA_HEADER_TYPE_MPLS,
    SYS_L2EDIT_EXTRA_HEADER_TYPE_NO_L2_EDIT
};
typedef enum sys_nh_l2_edit_extra_header_type_e sys_nh_l2_edit_extra_header_type_t;

enum sys_nh_ds_type_e
{
    SYS_NH_DS_TYPE_L3EDIT = 0,
    SYS_NH_DS_TYPE_L2EDIT,
    SYS_NH_DS_TYPE_DISCARD = 2,

    DS_TYPE_RESERVED
};
typedef enum sys_nh_ds_type_e sys_nh_ds_type_t;

enum sys_nh_entry_l3edit_type_e
{
    SYS_NH_L3EDIT_TYPE_NONE =0,
    SYS_NH_L3EDIT_TYPE_MPLS_4W,
    SYS_NH_L3EDIT_TYPE_RESERVED,
    SYS_NH_L3EDIT_TYPE_NAT_4W,
    SYS_NH_L3EDIT_TYPE_NAT_8W,
    SYS_NH_L3EDIT_TYPE_TUNNEL_V4,
    SYS_NH_L3EDIT_TYPE_TUNNEL_V6,
    SYS_NH_L3EDIT_TYPE_L3FLEX,
    SYS_NH_L3EDIT_TYPE_OF8W,
    SYS_NH_L3EDIT_TYPE_OF16W,
    SYS_NH_L3EDIT_TYPE_LOOPBACK,
    SYS_NH_L3EDIT_TYPE_TRILL,
    SYS_NH_L3EDIT_TYPE_MPLS_12W,
    SYS_NH_L3EDIT_TYPE_MAX
};
typedef enum sys_nh_entry_l3edit_type_e sys_nh_entry_l3edit_type_t;

struct sys_nh_offset_attr_s
{
    uint32 offset_base;
    uint16 entry_size;
    uint16 entry_num;
};
typedef struct sys_nh_offset_attr_s sys_nh_offset_attr_t;

struct sys_nh_table_entry_info_s
{
    uint32 table_id;
    uint8  entry_size;
    uint8  opf_pool_type;
    uint8  alloc_dir; /*0:forward  alloc ,1,reverse alloc*/
    uint8  table_8w;

    int32 (*p_func)(uint8, void*, void*, uint32*);
    int32 (*p_func_unmap)(uint8, void*, void*);
    int32 (*p_update)(uint8, void*);
};
typedef struct sys_nh_table_entry_info_s sys_nh_table_entry_info_t;


struct sys_dsl2edit_of6w_s
{
  uint8    vlan_profile_id;
  uint8 l2_rewrite_type;
  ctc_misc_nh_flex_edit_param_t* p_flex_edit;
};
typedef struct sys_dsl2edit_of6w_s  sys_dsl2edit_of6w_t;

struct sys_dsl2edit_s
{

    uint32 offset;

    uint8 ds_type;
    uint8 l2_rewrite_type;
    uint8 derive_mcast_mac_for_ip;
    uint8 is_vlan_valid;

    uint16 output_vlan_id;
    uint8 is_6w;
    uint8 dynamic;

    uint8 cos_domain;
    uint8 use_port_mac;
    uint8 update_mac_sa;
    uint8 strip_inner_vlan;

    mac_addr_t mac_da;
    mac_addr_t mac_sa;

    uint16  ether_type;
    uint8  is_span_ext_hdr;
    uint8 fpma;
    uint8 is_dot11;
    uint8 derive_mac_from_label;
    uint8 derive_mcast_mac_for_mpls;
    uint8 derive_mcast_mac_for_trill;
    uint8 map_cos;
    uint8 dot11_sub_type;
    uint32 dest_map;
    uint32 nexthop_ptr;
    uint8  nexthop_ext;
    uint8 bypass_ipe;
    uint8 bypass_igr_edit;
    uint8 reback;
    uint8 lb_with_ldp;
};
typedef struct sys_dsl2edit_s  sys_dsl2edit_t;

enum sys_usw_nh_param_type_e
{
    SYS_NH_PARAM_DSNH_TYPE_IPUC,
    SYS_NH_PARAM_DSNH_TYPE_BRGUC,
    SYS_NH_PARAM_DSNH_TYPE_BYPASS,
    SYS_NH_PARAM_DSNH_TYPE_IPMC,
    SYS_NH_PARAM_DSNH_TYPE_MPLS_PUSH_OP_NONE,
    SYS_NH_PARAM_DSNH_TYPE_MPLS_PUSH_OP_ROUTE,
    SYS_NH_PARAM_DSNH_TYPE_MPLS_PUSH_OP_L2VPN,
    SYS_NH_PARAM_DSNH_TYPE_MPLS_PHP,
    SYS_NH_PARAM_DSNH_TYPE_RSPAN,
    SYS_NH_PARAM_DSNH_TYPE_MPLS_OP_NONE,
    SYS_NH_PARAM_DSNH_TYPE_IPTUNNEL,
    SYS_NH_PARAM_DSNH_TYPE_TRILL,
    SYS_NH_PARAM_DSNH_TYPE_IPTUNNEL_FOR_MIRROR,
    SYS_NH_PARAM_DSNH_TYPE_XERSPAN,
    SYS_NH_PARAM_DSNH_TYPE_OF,
    SYS_NH_PARAM_DSNH_TYPE_WLANTUNNEL,
    SYS_NH_PARAM_DSNH_TYPE_SRV6,
    SYS_NH_PARAM_DSNH_TYPE_OVERLAY_VNI,
    MAX_SYS_NH_PARAM_DSNH_TYPE
}
;
typedef enum sys_usw_nh_param_type_e sys_usw_nh_param_type_t;

enum sys_usw_nh_param_flag_e
{
    SYS_NH_PARAM_FLAG_USE_TTL_FROM_PKT      = 0x0001,    /*PIPE/uniform  .uniform:SYS_NH_PARAM_FLAG_USE_TTL_FROM_PKT  =1*/
    SYS_NH_PARAM_FLAG_USE_MAPPED_STAG_COS   = 0x0002,   /*if set, cos will use qos mapped  cos,else use packet parsered cos or user defined */
    SYS_NH_PARAM_FLAG_USE_MAPPED_CTAG_COS   = 0x0004,   /*if set, dscp will use qos mapped  cos,else use packet parsered cos */
    SYS_NH_PARAM_FLAG_USE_MAPPED_DSCP       = 0x0008,     /*if set, dscp will use qos mapped  dscp,else use packet parsered dscp */
    SYS_NH_PARAM_FLAG_VPLS_NEXTHOP          = 0x0010,
    SYS_NH_PARAM_FLAG_LOGIC_PORT_CHECK      = 0x0020,
    SYS_NH_PARAM_FLAG_L2EDIT_AS_APS_GROUP   = 0x0040,
    SYS_NH_PARAM_FLAG_SWAP_MAC              = 0x0080,
    SYS_NH_PARAM_FLAG_IP_TUNNEL_PLD_BRIDGE  = 0x0100,
    SYS_NH_PARAM_FLAG_PHP_SHORT_PIPE        = 0x0200,    /*PHP Shore Pipe*/
    SYS_NH_PARAM_FLAG_ROUTE_NOTTL           = 0x0400,
    SYS_NH_PARAM_FLAG_STATS_EN              = 0x0800,
    SYS_NH_PARAM_FLAG_IP_TUNNEL_STRIP_VLAN   = 0x1000,
    SYS_NH_PARAM_FLAG_IP_TUNNEL_STRIP_INNER  = 0x2000,
    SYS_NH_PARAM_FLAG_ERSPAN_EN              = 0x4000,
    SYS_NH_PARAM_FLAG_ERSPAN_KEEP_IGS_TS     = 0x8000,
    SYS_NH_PARAM_FLAG_MISC_FLEX_PLD_BRIDGE   = 0x10000,
    SYS_NH_PARAM_FLAG_UDF_EDIT_EN            = 0x20000,
    SYS_NH_PARAM_FLAG_IP_TUNNEL_PLD_NONE     = 0x40000,
    SYS_NH_PARAM_FLAG_NAT                    = 0x80000,
    SYS_NH_PARAM_FLAG_IP_TUNNEL_STRIP_CVLAN  = 0x100000,
    SYS_NH_PARAM_FLAG_USE_COPY_DSCP          = 0x200000,
    MAX_SYS_NH_PARAM_FLAG
};
typedef enum sys_usw_nh_param_flag_e sys_usw_nh_param_flag_t;

struct sys_nh_param_dsnh_s
{
    uint32 dsnh_offset;
    uint32 l2edit_ptr;    /*arp*/
    uint32 lspedit_ptr;   /*spme/lsp*/
    uint32 l3edit_ptr;    /*inner l3/outer l3*/
    uint32 inner_l2edit_ptr;  /*inner l2*/
    uint16 fid;      /* used for overlaty tunnel only */
    uint16 span_id;
    ctc_vlan_egress_edit_info_t* p_vlan_info;
    uint16  dest_vlan_ptr;
    uint8   dsnh_type;    /*sys_usw_nh_param_type_t*/
    uint32  flag;
    uint8   use_ttl_from_pkt;
    uint8   hvpls;
    uint8   logic_port_check;
    uint8   dscp_en;
    uint16 logic_port;
    mac_addr_t macDa;        /**< 802.3 MAC address */

    uint8 hash_num;
    uint8 cw_index;
    uint8 spme_mode;
    uint8 wlan_tunnel_type;
    uint8 rid;
    uint8 wlan_mc_en;
    uint8 is_dot11;
    uint8 stag_en;
    uint8 mtu_no_chk;
    uint8 loop_edit;
    uint16 stats_ptr;
    uint16 cid;
	uint8 esi_id_index_valid;
    uint8 strip_l2_hdr;/*TMM .. */

    uint8 over_l2_edit:1;/*TMM...*/
    uint8 is_nat:1;/*TMM...*/
    uint8 only_l3edit:1;/*no l2edit, outer is l3edit*/
    uint8 dvp_tbl_valid:1;
    uint8 rsv0:4;

    uint32 svlan_tpid_en:1;
    uint32 svlan_tpid_index:2;
    uint32 is_leaf:1;
    uint32 pl_op:3;
    uint32 tag_disable:1;
    uint32 outer_edit_location : 1;
    uint32 rsv:23;
};
typedef struct sys_nh_param_dsnh_s sys_nh_param_dsnh_t;

struct sys_nh_param_hdr_s
{
    sys_usw_nh_type_t nh_param_type;
    sys_nh_entry_change_type_t change_type;
    uint32 nhid;
    uint8  is_internal_nh;
    uint8  have_dsfwd;
    uint8  have_dsfwd1;
    uint8  stats_valid;
    uint8  is_drop;
    uint32 stats_id;
    uint32 dsfwd_offset;
    uint32 stats_ptr;
    uint16 l3if_id;
    uint16 p_l3if_id;
    uint8 is_dsfwd1;/*AT, for acl or ecmp call nexthop need alloc dsfwd1*/
    uint8 dsnh_offset;/*AT, for multi pp, nh alloc in ctc*/
    uint8 is_update;
    uint8 xgpon_hybrid;
    sys_nh_info_ext_t* p_nh_info_ext;
};
typedef struct sys_nh_param_hdr_s sys_nh_param_hdr_t;

struct sys_nh_param_com_s
{
    sys_nh_param_hdr_t hdr;
};
typedef struct sys_nh_param_com_s sys_nh_param_com_t;

struct sys_nh_param_special_s
{
    sys_nh_param_hdr_t hdr;
};
typedef struct sys_nh_param_special_s sys_nh_param_special_t;

struct sys_nh_param_brguc_s
{
    sys_nh_param_hdr_t hdr;
    sys_nh_param_brguc_sub_type_t nh_sub_type;
    ctc_vlan_egress_edit_info_t* p_vlan_edit_info;
    ctc_vlan_egress_edit_info_t* p_vlan_edit_info_prot_path;
    uint32 dsnh_offset; /*Used for vlan editing*/
    uint32 gport; /*gport or aps bridge group id*/
    uint16 dest_vlan_ptr;
    uint32 loop_nhid;
    uint32    fwd_offset;
    ctc_vlan_edit_nh_param_t* p_vlan_edit_nh_param;
};
typedef struct sys_nh_param_brguc_s sys_nh_param_brguc_t;

struct sys_nh_param_mcast_s
{
    sys_nh_param_hdr_t hdr;
    uint32 groupid;        /*for mcast profile, means profile id*/
    uint8 opcode;
    uint8 is_mirror;
    uint8 is_mcast_profile;    /*means mcast group is mcast profile*/
    uint32 flag;
    uint32 profile_met_offset;
    sys_nh_param_mcast_member_t* p_member;
};
typedef struct sys_nh_param_mcast_s sys_nh_param_mcast_t;

struct sys_nh_param_ipuc_s
{
    sys_nh_param_hdr_t hdr;
    uint8 is_unrov_nh;
    ctc_ip_nh_param_t* p_ipuc_param;
};
typedef struct sys_nh_param_ipuc_s sys_nh_param_ipuc_t;

struct sys_nh_param_ecmp_s
{
    sys_nh_param_hdr_t hdr;
    ctc_nh_ecmp_nh_param_t* p_ecmp_param;
};
typedef struct sys_nh_param_ecmp_s sys_nh_param_ecmp_t;


/* IP Tunnel nexthop info*/
struct sys_nh_param_ip_tunnel_s
{
    sys_nh_param_hdr_t hdr;
    ctc_ip_tunnel_nh_param_t* p_ip_nh_param;
};
typedef struct sys_nh_param_ip_tunnel_s sys_nh_param_ip_tunnel_t;

struct sys_nh_param_wlan_tunnel_s
{
    sys_nh_param_hdr_t hdr;
    ctc_nh_wlan_tunnel_param_t* p_wlan_nh_param;
};
typedef struct sys_nh_param_wlan_tunnel_s sys_nh_param_wlan_tunnel_t;

struct sys_nh_param_trill_s
{
    sys_nh_param_hdr_t hdr;
    ctc_nh_trill_param_t* p_trill_nh_param;
};
typedef struct sys_nh_param_trill_s sys_nh_param_trill_t;

struct sys_nh_tunnel_ref_list_node_s
{
    struct sys_nh_tunnel_ref_list_node_s* p_next;
    void* p_ref_node;
};
typedef struct sys_nh_tunnel_ref_list_node_s sys_nh_tunnel_ref_list_node_t;


enum sys_nh_srh_flag_e
{
    SYS_NH_SRH_FLAG_DENY_REPLACE_IPDA       =  0x0001,
    SYS_NH_SRH_FLAG_APS                     =  0x0002,
};
typedef enum sys_nh_srh_flag_e sys_nh_srh_flag_t;

struct sys_nh_db_srh_pdata_s
{
    sys_nh_ref_list_node_t*  nh_list;
    sys_nh_tunnel_ref_list_node_t*  p_srh_list;
    sys_nh_ref_list_node_t*  ecmp_list;
};
typedef struct sys_nh_db_srh_pdata_s sys_nh_db_srh_pdata_t;

struct sys_nh_db_srh_s
{
    sys_nh_db_srh_pdata_t* pd;
    uint32 srh_id;
    uint32 p_srh_id;/*protection srh, for aps srh*/

    uint32 arp_id:20;/*aps group id, for aps srh*/
    uint32 is_reduce:1;
    uint32 alloc_en :1;
    uint32 segment_left:3;
    uint32 num        :3;
    uint32 rsv        :4;

    uint32 flag  :16;    /* sys_nh_srh_flag_t */
    uint32 l3edit_ptr:16;/*working srh, for aps srh*/
    uint32 ldp    :16;
    uint32 rsv1   :16;
};
typedef struct sys_nh_db_srh_s sys_nh_db_srh_t;

struct sys_nh_param_srv6_s
{
    sys_nh_param_hdr_t hdr;
    ctc_nh_srv6_param_t* p_srv6_nh_param;
    ctc_nh_oif_info_t oif;
    mac_addr_t mac;
    sys_com_ldp_update_t* p_ldp_update;
    sys_nh_db_srh_t* p_tnl;
};
typedef struct sys_nh_param_srv6_s sys_nh_param_srv6_t;

struct sys_nh_param_ol_vni_s
{
    sys_nh_param_hdr_t hdr;
    ctc_nh_ol_vni_t* p_ol_vni_param;
};
typedef struct sys_nh_param_ol_vni_s sys_nh_param_ol_vni_t;

struct sys_nh_param_overlay_s
{
    sys_nh_param_hdr_t hdr;
    ctc_nh_overlay_param_t* p_overlay_nh_param;
    sys_com_ldp_update_t* p_ldp_update;
};
typedef struct sys_nh_param_overlay_s sys_nh_param_overlay_t;

struct sys_nh_param_iloop_s
{
    sys_nh_param_hdr_t hdr;
    ctc_loopback_nexthop_param_t* p_iloop_param;
};
typedef struct sys_nh_param_iloop_s sys_nh_param_iloop_t;

struct sys_nh_param_rspan_s
{
    sys_nh_param_hdr_t hdr;
    ctc_rspan_nexthop_param_t* p_rspan_param;
    uint32 dsnh_offset;
};
typedef struct sys_nh_param_rspan_s sys_nh_param_rspan_t;

struct sys_nh_param_crscnt_s
{
    bool swap_mac;
    uint16 srcport;
    uint16 destport;
};
typedef struct sys_nh_param_crscnt_s sys_nh_param_crscnt_t;

struct sys_nh_param_misc_s
{
    sys_nh_param_hdr_t hdr;
    ctc_misc_nh_param_t* p_misc_param;
    uint32 xeditptr;
};
typedef struct sys_nh_param_misc_s sys_nh_param_misc_t;


struct sys_nh_info_arp_param_s
{
    uint8 nh_entry_type; /*sys_usw_nh_type_t*/
    uint32 nh_id;
    uint8 is_aps;
    uint8 use_l2edit;
    uint8 use_static_l2edit;
    uint32 (* updateNhp)(uint8 lchip, void* arp_info, uint32 nh_id);
    void* p_arp_nh_node;
};
typedef struct sys_nh_info_arp_param_s sys_nh_info_arp_param_t;

enum sys_nh_arp_flag_e
{
    SYS_NH_ARP_FLAG_DROP                =  0x01,
    SYS_NH_ARP_FLAG_REDIRECT_TO_CPU     =  0x02,
    SYS_NH_ARP_VLAN_VALID               =  0x04,
    SYS_NH_ARP_ECMP_IF                  =  0x08,
    SYS_NH_ARP_PORT_VALID               =  0x10,
    SYS_NH_ARP_IPUC_L2_EDIT             =  0x20,
    SYS_NH_ARP_CVLAN_VALID              =  0x40,
    SYS_NH_ARP_L3IF_VALID               =  0x80,

    SYS_NH_ARP_MAX
};
typedef enum sys_nh_arp_flag_e sys_nh_arp_flag_t;

struct sys_nh_db_arp_nh_node_s
{
    ctc_list_pointer_node_t head;
    uint32 nhid;
};
typedef struct sys_nh_db_arp_nh_node_s sys_nh_db_arp_nh_node_t;


struct sys_nh_db_arp_pdata_s
{
    uint32 (* updateNhp)(uint8 lchip, void* arp_info, uint32 nh_id);
    ctc_list_pointer_t*  nh_list;
};
typedef struct sys_nh_db_arp_pdata_s sys_nh_db_arp_pdata_t;

struct sys_nh_db_arp_s
{
    sys_nh_db_arp_pdata_t* pd;
    uint32  arp_id   :20;
    uint32  output_vid:12;

    uint32  l3if_id   :16;
    uint32  ldp_mac_profile : 8;
    uint32  l3if_type :3;       /**< the type of l3interface , CTC_L3IF_TYPE_XXX */
    uint32  output_vlan_is_svlan:1;       /**< the type of l3interface , CTC_L3IF_TYPE_XXX */
    uint32  is_8w    : 1;
    uint32  rsv:3;

    uint32  offset      :16;          /**< static outer l2 edit for mpls/tunnel vlan & mac edit*/
    uint32  offset_dyn  :16;          /**< dynamic l2 edit for ipuc vlan edit*/

    uint32  output_cvid    :12;     /**< valid in double tag sub if case, output by interface */
    uint32  destmap_profile:12;  /**< destmap profile id, used for mpls and tunnel, 0 means do not use destmap profile*/
    uint32  flag           :8;

    uint32  ref_cnt  : 16;
    uint32  rsv1  : 16;

    uint32  gport;            /**< outgoing port*/
    uint32  dsfwd_offset;
    mac_addr_t mac_da;
};
typedef struct sys_nh_db_arp_s sys_nh_db_arp_t;

struct sys_nh_db_ol_tunnel_s
{
    sys_nh_ref_list_node_t* p_ref_nh_list;

    uint32 gport;
    uint32 logic_port;
    uint32 ul_nhid;
    uint32 dot1ae_channel;/*for at, means fp_id*/

    uint32 flag  :16;           /* sys_nh_ip_tunnel_flag_t */
    uint32 dsl3edit_offset:16;

    uint32 arp_id:20;
    uint32 dot1ae_en      : 1;
    uint32 sci_en         : 1;
    uint32 is_4x          : 1;
    uint32 vxlan_edit_idx : 3;
    uint32 tunnel_type    : 2;
    uint32 ul_nh_en       : 1;
    uint32 rsv            : 3;

    uint32 ecmp_if_id:16;
    uint32 sa_index:8;
    uint32 sc_index:8;

};
typedef struct sys_nh_db_ol_tunnel_s sys_nh_db_ol_tunnel_t;

struct sys_dsl2edit_eth_s
{
    uint8 is_8w;

    uint8 ds_type;
    uint8 l2_rewrite_type;
    mac_addr_t mac_da;
    uint8 strip_inner_vlan;
    uint16 output_vid;
    uint8  output_vlan_is_svlan;
    uint8 is_share_mac;
    uint8 fpma;
    uint8 is_dot11;
    uint8 derive_mac_from_label;
    uint8 derive_mcast_mac_for_mpls;
    uint8 derive_mcast_mac_for_trill;
    uint8 map_cos;
    uint8 dot11_sub_type;
    uint8 derive_mcast_mac_for_ip;
    uint8 mac_da_en;
    uint32 offset;
    uint8 output_vid_valid;
    uint32 xeditptr;

    /*8w from here*/
    mac_addr_t mac_sa;
    uint8 update_mac_sa;
    uint8 cos_domain;
    uint16 ether_type;
    uint8 use_port_mac;
    uint8  is_span_ext_hdr;
    uint16 output_cvid;
    uint8 output_cvid_valid;
};
typedef struct sys_dsl2edit_eth_s sys_dsl2edit_eth_t;

struct sys_dsl3edit_tunnelv4_s
{

    uint8 share_type;

    uint8 ds_type;
    uint8 l3_rewrite_type;
    uint8 map_ttl;
    uint8 ttl;
    uint8 copy_dont_frag;
    uint8 dont_frag;
    uint8 derive_dscp;  /*1:use assign; 1: map; 2:copy*/
    uint8 dscp;
    uint8 dscp_domain;

    uint8 ip_protocol_type;
    uint16 mtu_size;

    uint32 ipda;
    uint32 ipsa;
    uint32 ipsa_6to4;
    uint8 ipsa_valid;
    uint8 ipsa_index;

    uint8 inner_header_valid;
    uint8 inner_header_type;
    uint32 stats_ptr;

    uint16 gre_protocol;
    uint8 gre_version;
    uint8 gre_flags;
    uint32 gre_key;

    uint8 tunnel6_to4_da;
    uint8 tunnel6_to4_sa;
    uint8 tunnel6_to4_da_ipv4_prefixlen;
    uint8 tunnel6_to4_da_ipv6_prefixlen;
    uint8 tunnel6_to4_sa_ipv4_prefixlen;
    uint8 tunnel6_to4_sa_ipv6_prefixlen;

    uint8 xerspan_hdr_en;
    uint8 xerspan_hdr_with_hash_en;

    uint32 l2edit_ptr;

    uint8 evxlan_protocl_index; /* use for getting protocl from EpePktProcCtl.array[evxlan_protocl_index].vxlanProtocolType,
       how to config the index refer to sys_usw_overlay_tunnel_init(lchip)*/
    uint8 is_evxlan:1;
    uint8 is_geneve:1;
    uint8 udp_src_port_en:1;  /* used for vxlan udp src port */
    uint8 rmac_en:1;
    uint8 encrypt_en:1;
    uint8 isatp_tunnel:1;
    uint8 mtu_check_en:1;
    uint8 out_l2edit_valid:1;

    uint8 is_gre_auto   : 1;
    uint8 is_vxlan_auto : 1;
    uint8 int_en:1;
    uint8 is_vxlan_gbp:1;
    uint8 vxlan_edit_idx:4;
    uint16 l4_src_port;
    uint16 l4_dest_port;
    uint8 encrypt_id;
    uint16 bssid_bitmap;
    uint8 data_keepalive;
    uint8 ecn_mode;  /*0:copy, 1:map*/

    uint8 sc_index;
    uint8 sci_en : 1;
    uint8 cloud_sec_en    : 1;
    uint8 udf_profile_id  : 6;

    uint16 udf_edit[4];
    uint32 xedit_ptr;
    uint8 is_12w:1;
    uint8 rsv:7;

};
typedef struct sys_dsl3edit_tunnelv4_s  sys_dsl3edit_tunnelv4_t;

struct sys_dsl3edit_tunnelv6_s
{

    uint8 share_type;

    uint8 ds_type;
    uint8 l3_rewrite_type;
    uint8 map_ttl;
    uint8 ttl;
    uint8 derive_dscp;
    uint8 tos;
    uint8 dscp_domain;

    uint8 ip_protocol_type;
    uint16 mtu_size;

    ipv6_addr_t ipda;
    uint8 ipsa_index;

    uint8 inner_header_valid;
    uint8 inner_header_type;
    uint32 stats_ptr;

    uint16 gre_protocol;
    uint8 gre_version;
    uint8 gre_flags;
    uint32 gre_key;

    uint8 new_flow_label_valid;
    uint8 new_flow_label_mode;
    uint32 flow_label;

    uint8 xerspan_hdr_with_hash_en;
    uint32 l2edit_ptr;

    uint8 evxlan_protocl_index; /* use for getting protocl from EpePktProcCtl.array[evxlan_protocl_index].vxlanProtocolType,
       how to config the index refer to sys_usw_overlay_tunnel_init(lchip)*/

    uint8 is_gre_auto   : 1;
    uint8 is_vxlan_auto : 1;
    uint8 int_en:1;
    uint8 is_vxlan_gbp:1;
    uint8 auto_protocol:1;
    uint8 rsv          :3;
    uint16 l4_dest_port;
    uint16 l4_src_port;
    uint8 encrypt_id;
    uint16 bssid_bitmap;
    uint8 data_keepalive;
    uint8 ecn_mode;  /*0:copy, 1:map*/

    uint8 is_geneve     : 1;
    uint8 xerspan_hdr_en : 1;
    uint8 mtu_check_en : 1;
    uint8 out_l2edit_valid : 1;
    uint8 is_evxlan : 1;
    uint8 udp_src_port_en : 1;  /* used for vxlan udp src port */
    uint8 encrypt_en : 1;
    uint8 rmac_en : 1;

    uint8 sc_index;
    uint8 sci_en : 1;
    uint8 cloud_sec_en    : 1;
    uint8 udf_profile_id  : 6;

    uint16 udf_edit[4];
    uint8 vxlan_edit_idx;
    uint32 xedit_ptr;

};
typedef struct sys_dsl3edit_tunnelv6_s  sys_dsl3edit_tunnelv6_t;

struct sys_dsl3edit_nat4w_s
{
    uint8 ds_type;
    uint8 l3_rewrite_type;
    uint8 ip_da_prefix_length;
    uint8 ipv4_embeded_mode;

    uint32 l2edit_ptr;

    uint32 ip;
    uint32 mask;
    uint16 l4_port;
    uint16 replace_ip_da:2;
    uint16 replace_l4_dest_port:1;
    uint16 replace_ip_sa:2;
    uint16 replace_l4_src_port:1;
    uint16 nat_sa:1;
    uint16 out_l2edit_valid:1;
    uint16 sub_net:1;
    uint16 rsv:7;
};
typedef struct sys_dsl3edit_nat4w_s  sys_dsl3edit_nat4w_t;

struct sys_dsl3edit_nat8w_s
{
    uint8 ds_type;
    uint8 l3_rewrite_type;
    uint8 ip_da_prefix_length;
    uint8 ipv4_embeded_mode;

    ipv6_addr_t ipda;
    ipv6_addr_t mask;
    uint16 l4_dest_port;
    uint16 l4_src_port;
    uint32 l2edit_ptr;
    uint32 replace_ip_da:2;
    uint32 replace_ip_sa:2;
    uint32 replace_l4_dest_port:1;
    uint32 nat_sa:1;
    uint32 replace_l4_src_port:1;
    uint32 out_l2edit_valid:1;
    uint32 sub_net:1;
    uint32 rsv:23;

};
typedef struct sys_dsl3edit_nat8w_s  sys_dsl3edit_nat8w_t;

struct sys_dsmpls_s
{

    uint32 offset;

    uint8 ds_type;
    uint8 l3_rewrite_type;
    uint8 next_editptr_valid;
    uint8 outer_editptr_type;
    uint16 outer_editptr;

    uint16 logic_dest_port;
    uint16 mpls_oam_index;
    uint8 oam_en;
    uint32 statsptr;

    uint32 label;
    uint8 label_type;
    uint8 mcast_label;
    uint8 entropy_label_en;
    uint8 src_dscp_type;
    uint8 derive_label;
    uint16 derive_exp;
    uint8 exp;
    uint8 map_ttl_mode;
    uint8 map_ttl;
    uint8 ttl_index;
    uint8 mpls_domain;
    uint8 discard;
    uint8 discard_type;

    uint32 label_full[10];    /*label+ttl+exp*/
    uint8  label_num;
    uint8 edit_mode; /*TMM. 1:insert, do not strip l2*/
    uint8 eslb_en;

};
typedef struct sys_dsmpls_s  sys_dsmpls_t;

struct sys_dsl3edit_srv6_s
{
    uint32 share_type:4;
    uint32 ds_type:8;
    uint32 l3_rewrite_type:8;
    uint32 ttl:8;
    uint32 map_ttl:1;
    uint32 derive_dscp:3;

    uint32 tos:8;
    uint32 dscp_domain:8;
    uint32 mtu_size:16;

    uint32 ecn_mode:2;  /*0:copy, 1:map*/
    uint32 mtu_check_en:1;
    uint32 out_l2edit_valid:1;
    uint32 replace_last:1;
    uint32 new_flow_label_valid:1;
    uint32 new_flow_label_mode:4;
    uint32 header_type:8;
    uint32 next_header:8;
    uint32 next_header_en:1;
    uint32 upd_chksum:1;
    uint32 rsv:4;

    uint32 stats_ptr;
    uint32 flow_label;
    uint32 l2edit_ptr;

    ipv6_addr_t ipda;
    ipv6_addr_t vpn_sid;
    uint8 ipsa_index;
    uint32 xedit_ptr;
};
typedef struct sys_dsl3edit_srv6_s  sys_dsl3edit_srv6_t;

#define SYS_L3EDIT_RAW_LEN_MAX 4
struct sys_dsl3edit_raw_s
{
    uint8 data_len;
    uint32 data[SYS_L3EDIT_RAW_LEN_MAX];
};
typedef struct sys_dsl3edit_raw_s  sys_dsl3edit_raw_t;

struct sys_nh_db_edit_spool_s
{
    uint32 edit_type :8;    /* [input][spool_db]sys_nh_entry_table_type_t*/
    uint32 offset    :24;   /* [input][ouput][spool_db][nh_db]*/
    uint32 calc_len[0];

    void* ds;               /* [input] */
    uint8 lchip;            /* [input] */
};
typedef struct sys_nh_db_edit_spool_s sys_nh_db_edit_t;

struct sys_nh_info_special_s
{
    sys_nh_info_com_hdr_t hdr;
    uint32 dest_gport;
};
typedef struct sys_nh_info_special_s sys_nh_info_special_t;

struct sys_nh_info_rspan_s
{
    sys_nh_info_com_hdr_t hdr;
    uint8 remote_chip;
    uint8 rsv[3];
};
typedef struct sys_nh_info_rspan_s sys_nh_info_rspan_t;
enum sys_nh_brguc_flag_e
{
    SYS_NH_BRGUC_LOOP_NH       =  0x01,
    SYS_NH_BRGUC_FLAG_MAX
};
struct sys_nh_info_brguc_s
{
    sys_nh_info_com_hdr_t hdr;

    uint32 l2_edit_ptr:20;
    uint32 nh_sub_type:4;
    uint32 flag:8;

    uint32 dest_gport;
    uint32 service_id:16;
    uint32 dest_logic_port:16;
};
typedef struct sys_nh_info_brguc_s sys_nh_info_brguc_t;

struct sys_nh_info_ipuc_edit_info_s{

   uint16  l3ifid;
   uint32  arp_id;
   mac_addr_t  mac_da;
   uint32 l2_edit_ptr;
};
typedef struct sys_nh_info_ipuc_edit_info_s sys_nh_info_ipuc_edit_info_t;

struct sys_nh_oam_info_s
{
    uint32 mep_index : 16;
    uint32 mep_type  : 8;
    uint32 mep_lchip  :8;
    uint16 ref_cnt;
};
typedef struct sys_nh_oam_info_s sys_nh_oam_info_t;

struct sys_nh_ref_oam_node_s
{
    sys_nh_oam_info_t ref_oam;
    struct sys_nh_ref_oam_node_s* p_next;
};
typedef struct sys_nh_ref_oam_node_s sys_nh_ref_oam_node_t;

enum sys_nh_ipuc_flag_e
{
    SYS_NH_IPUC_FLAG_MERGE_DSFWD        = 0x0001,
    SYS_NH_IPUC_FLAG_REPLACE_MODE_EN    = 0x0002,
    SYS_NH_IPUC_FLAG_L3IF_VALID         = 0x0004,
    SYS_NH_IPUC_FLAG_FPMA               = 0x0008
};
typedef enum sys_nh_ipuc_flag_e sys_nh_ipuc_flag_t;

struct sys_nh_info_ipuc_pdata_s
{
    sys_nh_ref_oam_node_t* oam_list;   /*sys_nh_ref_list_node_t*/
    sys_nh_db_arp_nh_node_t* p_arp_nh_node;/*used for unbind*/
    sys_nh_info_bind_t* bind_data;
};
typedef struct sys_nh_info_ipuc_pdata_s sys_nh_info_ipuc_pdata_t;


struct sys_nh_info_ipuc_s
{
    sys_nh_info_com_hdr_t             hdr;
    sys_nh_info_ipuc_pdata_t* pd;

    uint32 gport;

    uint32 l2_edit_ptr:19;
    uint32 l3ifid   :13;

    uint32 arp_id   :20;
    uint32 adjust_len:8;
    uint32 l2edit_8w:1;
    uint32 ldp_ext_alloc:1;
    uint32 rsv:2;

    uint32 flag     :16;
    uint32 ldp_ext  :16;
};
typedef struct sys_nh_info_ipuc_s sys_nh_info_ipuc_t;

enum sys_nh_dsmet_flag_e
{
    SYS_NH_DSMET_FLAG_IS_LINKAGG              =  0x0001,
    SYS_NH_DSMET_FLAG_ENDLOCAL                =  0x0002,
    SYS_NH_DSMET_FLAG_PORT_CHK_DISCARD        =  0x0004,
    SYS_NH_DSMET_FLAG_LOGIC_PORT_CHK          =  0x0008,
    SYS_NH_DSMET_FLAG_USE_DSNH8W              =  0x0010,
    SYS_NH_DSMET_FLAG_USE_PBM                 =  0x0020,
    SYS_NH_DSMET_FLAG_USE_RSV_NH              =  0x0040,
    SYS_NH_DSMET_FLAG_APS_SHARE_NH            =  0x0080,
    SYS_NH_DSMET_FLAG_HORIZON_SPLIT_EN        =  0x0100,
    SYS_NH_DSMET_FLAG_REFECTIVE               =  0x0200,
    SYS_NH_DSMET_FLAG_DESTMAP_PROFILE         =  0x0400,
    SYS_NH_DSMET_FLAG_LEAF_CHECK_EN           =  0x0800,
    SYS_NH_DSMET_FLAG_CLOUD_SEC_EN            =  0x1000,
    SYS_NH_DSMET_FLAG_APPEND_DROP             =  0x2000,
    SYS_NH_DSMET_FLAG_LOGIC_REPLI_EN          =  0x4000,/*Fot TM2 Logic Rep*/
    SYS_NH_DSMET_FLAG_IS_MCAST_APS            =  0x8000,
    SYS_NH_DSMET_FLAG_IS_BASIC_MET            =  0x10000,
    SYS_NH_DSMET_FLAG_LOGIC_REPLI_ABILITY     =  0x20000,
    SYS_NH_DSMET_FLAG_1ST_VLANIF              =  0x40000,
    SYS_NH_DSMET_FLAG_LDP_EXT_EN              =  0x80000,
    SYS_NH_DSMET_FLAG_MAX
};
typedef enum sys_nh_dsmet_flag_e sys_nh_dsmet_flag_t;

struct sys_nh_info_dsmet_s
{
    uint32   flag; /*sys_nh_dsmet_flag_t,SYS_NH_DSMET_FLAG_XX*/
    uint32   ref_nhid;
    uint32   dsnh_offset;

    uint32   dsmet_offset:20;
    uint32   vid:12; /*For IPMC*/

    uint32   next_dsmet_offset:20;
    uint32   cvid:12;

    uint32   logic_port:16;
    uint32   ucastid:16;

    uint32   replicate_num:16; /*replicate_num for IPMC; port num of l2mc port bitmap;*/
    uint32   fid:16;

    uint32    entry_type:8;
    uint32    free_dsnh_offset_cnt:4;
    uint32    member_type:4;
    uint32    port_type:4;  /*For TMM logic rep, means lastRep, should set to 1 on the last but one node*/
    uint32    min_port_range:4;/*portid >> 5, means words range, 512 port to 0~15 word*/
    uint32    max_port_range:4;/*portid >> 5, means words range, 512 port to 0~15 word*/
    uint32    rsv:4;

    ctc_list_pointer_t logic_rep_list;  /*TMM, used for logic replicate*/
    uint16*  vid_list;
};
typedef struct sys_nh_info_dsmet_s sys_nh_info_dsmet_t;
struct sys_nh_mcast_meminfo_s
{
    ctc_list_pointer_node_t list_head;
    sys_nh_info_dsmet_t dsmet;
};
typedef struct sys_nh_mcast_meminfo_s sys_nh_mcast_meminfo_t;

struct sys_nh_mcast_meminfo_param_s
{
    ctc_list_pointer_node_t list_head;
    sys_nh_info_dsmet_t dsmet;
    sys_nh_param_mcast_member_t member;
};
typedef struct sys_nh_mcast_meminfo_param_s sys_nh_mcast_meminfo_param_t;


struct sys_nh_info_ecmp_s
{
    sys_nh_info_com_hdr_t hdr;

    uint32* nh_array;/*all nh member, [valid_nh, valid_nh, ..., valid_nh, unrov_nh, unrov_nh, ...]*/

    uint16 l3edit_offset_base;
    uint16 l2edit_offset_base;
    uint16 gport;
    uint16 ecmp_member_base;

    uint32 ecmp_cnt         :12;    /*include unresoved nh member, ecmp_cnt = valid_cnt + unrov_nh_cnt*/
    uint32 valid_cnt        :12;    /*valid member*/
    uint32 ant_flow_base    :8;

    uint32 mem_num          :13;  /*max member num in group*/
    uint32 ecmp_group_id    :12;
    uint32 type             :3;  /*ctc_nh_ecmp_type_t*/
    uint32 h_ecmp_en        :1;
    uint32 ant_flow_en      :1;
    uint32 failover_en      :1;
    uint32 random_rr_en     :1;

    uint32 rpf_id           :9;
    uint32 rpf_en           :1;
    uint32 stats_valid      :1;
    uint32 mem_is_tunnel    :1;
    uint32 tunnel_is_ldp    :1;
    uint32 srh_replace_ipda :1;
    uint32 rsv              :18;
};
typedef struct sys_nh_info_ecmp_s sys_nh_info_ecmp_t;

enum sys_nh_mpls_tunnel_flag_e
{
    SYS_NH_MPLS_TUNNEL_FLAG_STATS          =  0x01,
    SYS_NH_MPLS_TUNNEL_FLAG_APS  =  0x02,
    SYS_NH_MPLS_TUNNEL_FLAG_TWO_LAYER_APS  =  0x04,
    SYS_NH_MPLS_TUNNEL_FLAG_WORKING  =  0x08,
    SYS_NH_MPLS_TUNNEL_FLAG_PROTECTION  =  0x10,
    SYS_NH_MPLS_TUNNEL_FLAG_EXSIT_SPME  =  0x20,
    SYS_NH_MPLS_TUNNEL_FLAG_IS_SPME  =  0x40,
    SYS_NH_MPLS_TUNNEL_FLAG_IS_L2EDIT8W  =  0x80,
    SYS_NH_MPLS_TUNNEL_FLAG_IS_SR  =  0x100,
    SYS_NH_MPLS_TUNNEL_FLAG_TWO_LAYER_PROTECTION  =  0x200,
    SYS_NH_MPLS_TUNNEL_FLAG_APS_SEPARATE = 0x400,
    SYS_NH_MPLS_TUNNEL_FLAG_LB_WITH_LOGIC_DST = 0x800,
    SYS_NH_MPLS_TUNNEL_FLAG_MAX
};

enum sys_nh_aps_e
{
    SYS_NH_APS_W,
    SYS_NH_APS_P,
    SYS_NH_APS_M
};

struct sys_nh_mpls_sr_s
{
    uint32 dsnh_offset;
    uint32 pw_offset:16;
    uint32 lsp_offset:16;
    uint32 spme_offset:16;
    uint32 l2edit_offset:16;
};
typedef struct sys_nh_mpls_sr_s sys_nh_mpls_sr_t;

struct sys_nh_info_mpls_tnl_pdata_s
{
    sys_nh_tunnel_ref_list_node_t*  p_tunnel_list;
    sys_nh_ref_list_node_t* p_ref_nh_list;   /*sys_nh_ref_list_node_t*/
    sys_nh_mpls_sr_t* sr;
};
typedef struct sys_nh_info_mpls_tnl_pdata_s sys_nh_info_mpls_tnl_pdata_t;

struct sys_nh_db_mpls_tunnel_s
{
    sys_nh_info_mpls_tnl_pdata_t* pd;
    uint32  gport;                 /*if SYS_NH_MPLS_TUNNEL_FLAG_APS is set, it is aps group id*/
    uint32 loop_nhid;

    uint32  l3ifid:14;                /*for tunnel aps means work mpls tuunel id*/
    uint32  p_l3ifid:14;              /*for tunnel aps means protect mpls tuunel id*/
    uint32  spme_ttl_high:4;

    uint32  tunnel_id:16;
    uint32  flag:16; /*sys_nh_mpls_tunnel_flag_e,SYS_NH_MPLS_TUNNEL_FLAG_XX*/

    uint32  label_num:8;
    uint32  sr_loop_num:8;
    uint32  l2edit_offset:16;

    uint32  spme_offset:16;
    uint32  lsp_offset:16;

    uint32  arp_id:20;
    uint32  lsp_ttl:8;
    uint32  spme_ttl_low:4;

};
typedef struct sys_nh_db_mpls_tunnel_s sys_nh_db_mpls_tunnel_t;

struct sys_nh_info_mpls_pdata_s
{
    sys_nh_ref_oam_node_t* oam_list;
    sys_nh_info_bind_t* bind_data;
};
typedef struct sys_nh_info_mpls_pdata_s sys_nh_info_mpls_pdata_t;

struct sys_nh_info_mpls_s
{
    sys_nh_info_com_hdr_t hdr;
    sys_nh_info_mpls_pdata_t* pd;

    uint32   gport;

    uint32 outer_l2_ptr:16;

    uint32 inner_l2_ptr:16;

    uint32 dsl3edit_offset:16;
    uint32 l3ifid:13;
    uint32  ttl_mode  : 2;
    uint32  is_hvpls  : 1;

    uint32 dest_logic_port:16; /*H-vpls*/
    uint32 service_id:16; /*Service Qos*/

    uint32 arp_id:20;
    uint32 rsv:12;

    uint32 tunnel_id:16;
    uint32 tunnel_id_valid:1;
    uint32 rsv1:15;

    uint32  adjust_len:8;
    uint32  nh_prop   : 2;
    uint32  op_code   : 2;
    uint32  cw_index:4;
    uint32  ttl:8;
    uint32  svlan_edit_type : 3;
    uint32  cvlan_edit_type : 3;
    uint32  is_loop_nh   : 1;
    uint32  aps_xcon_met: 1;
    uint32  met_offset;
};
typedef struct sys_nh_info_mpls_s sys_nh_info_mpls_t;

struct sys_nh_param_mpls_s
{
    sys_nh_param_hdr_t hdr;
    ctc_mpls_nexthop_param_t* p_mpls_nh_param;
    sys_nh_db_mpls_tunnel_t* p_mpls_tunnel;
    uint32 oam_lm_en      : 1;
    uint32 p_oam_lm_en    : 1;
    uint32 oam_lock_en    : 1;
    uint32 p_oam_lock_en  : 1;
    uint32 oam_mep_index  : 12;
    uint32 p_oam_mep_index  : 12;
    uint32 is_working     : 1;
    uint32 rsv            : 3;
};
typedef struct sys_nh_param_mpls_s sys_nh_param_mpls_t;

enum sys_nh_ip_tunnel_flag_e
{
    SYS_NH_IP_TUNNEL_FLAG_IN_V4       =  0x0001,
    SYS_NH_IP_TUNNEL_FLAG_IN_V6       =  0x0002,
    SYS_NH_IP_TUNNEL_FLAG_IVI_6TO4    =  0x0004,
    SYS_NH_IP_TUNNEL_FLAG_IVI_4TO6    =  0x0008,
    SYS_NH_IP_TUNNEL_FLAG_NAT_V4      =  0x0010,
    SYS_NH_IP_TUNNEL_FLAG_L2EDIT8W    =  0x0020,
    SYS_NH_IP_TUNNEL_REROUTE          =  0x0040,
    SYS_NH_IP_TUNNEL_KEEP_IGS_TS      =  0x0080,
    SYS_NH_IP_TUNNEL_LOOP_NH          =  0x0100,
    SYS_NH_IP_TUNNEL_NVGRE            =  0x0200,
    SYS_NH_IP_TUNNEL_HAVE_IPSA        =  0x0400,
    SYS_NH_IP_TUNNEL_FLAG_NAT_V6      =  0x0800,
    SYS_NH_IP_TUNNEL_FLAG_NAT64       =  0x1000,
    SYS_NH_IP_TUNNEL_FLAG_DSFWD       =  0x2000,
    SYS_NH_IP_TUNNEL_FLAG_NSH_EN      =  0x4000,
    SYS_NH_IP_TUNNEL_FLAG_NAT_MASK    =  0x8000,
    SYS_NH_IP_TUNNEL_FLAG_MAX
};
typedef enum sys_nh_ip_tunnel_flag_e sys_nh_ip_tunnel_flag_t;
enum sys_nh_ol_tunnel_flag_e
{
    SYS_NH_OL_TUNNEL_FLAG_IN_V4       =  0x0001,
    SYS_NH_OL_TUNNEL_FLAG_IN_V6       =  0x0002,
    SYS_NH_OL_TUNNEL_REROUTE          =  0x0004,
    SYS_NH_OL_TUNNEL_HAVE_IPSA        =  0x0008,
    SYS_NH_OL_TUNNEL_FLAG_DSFWD       =  0x0010,
    SYS_NH_OL_TUNNEL_FLAG_NSH_EN      =  0x0020,
    SYS_NH_OL_TUNNEL_DIRTY            =  0x0040,
    SYS_NH_OL_TUNNEL_FLAG_MAX
};
typedef enum sys_nh_ol_tunnel_flag_e sys_nh_ol_tunnel_flag_t;

struct sys_nh_vxlan_hw_profile_s
{
    /*compared key*/
    uint32 flags:8;
    uint32 udp_dest_port:16;
    uint32 rsv1:8;

    uint32 rsv2:8;
    uint32 rsv3:8;
    uint32 rsv7:8;
    uint32 rsv3_as_etype:1;
    uint32 rsv3_as_protocol:2;
    uint32 with_policy_group:1;
    uint32 rsv:4;

    uint32 calc_key_len[0];

    /*index and reference count, no need to compare*/
    uint32 profile_idx:8;
    uint32 ref_cnt:24;
};
typedef struct sys_nh_vxlan_hw_profile_s sys_nh_vxlan_hw_profile_t;

struct sys_nh_info_ip_tunnel_s
{
    sys_nh_info_com_hdr_t hdr;
    sys_nh_info_bind_t* bind_data;

    uint32 gport;
    uint32 vn_id;
    uint32 dot1ae_channel;
    uint32 ctc_flag;      /*used for get nh parameter*/

    uint32 dest_vlan_ptr:16;
    uint32 l3ifid       :16;

    uint32 flag            :16;           /* sys_nh_ip_tunnel_flag_t, NOTICE: Flag only have 16 bits, addition flag using bit operation*/
    uint32 dsl3edit_offset :16;
    uint32 inner_l2_edit_offset :16;
    uint32 outer_l2_edit_offset :16;

    uint32 span_id        :10;
    uint32 udf_profile_id :6;
    uint32 sa_index       :8;
    uint32 adjust_len     :8;

    uint32 dest_logic_port:16; /*H-overlay*/
    uint32 sc_index       :7;
    uint32 is_12w         :1;
    uint8  tunnel_type    :5;
    uint32 inner_pkt_type :3;

    uint32 arp_id         :20;
    uint32 vxlan_edit_idx :4;
    uint32 share_type     :3;    /*used for get nh parameter*/
    uint32 flow_flag_valid:1;
    uint32 sci_en         :1;
    uint32 dot1ae_en      :1;
    uint32 bind_ldp       :1;
    uint32 rsv            :1;
};
typedef struct sys_nh_info_ip_tunnel_s sys_nh_info_ip_tunnel_t;

enum sys_nh_wlan_tunnel_flag_e
{
    SYS_NH_WLAN_TUNNEL_FLAG_IN_V4       =  0x0001,
    SYS_NH_WLAN_TUNNEL_FLAG_IN_V6       =  0x0002,
    SYS_NH_WLAN_TUNNEL_HAVE_IPSA         =  0x0004,
    SYS_NH_WLAN_TUNNEL_FLAG_MAX
};
typedef enum sys_nh_wlan_tunnel_flag_e sys_nh_wlan_tunnel_flag_t;

struct sys_nh_info_wlan_tunnel_s
{
    sys_nh_info_com_hdr_t hdr;
    uint32 gport;
    uint32 dsl3edit_offset;
    uint32 inner_l2_ptr;

    uint32 dest_vlan_ptr:16;
    uint32 rsv:16;

    uint32  flag:8; /* sys_nh_wlan_tunnel_flag_t */
    uint32 sa_index:8;
    uint32  use_multi_l2_ptr:8;   /*for l3 mcast fallbackbridge*/
    uint32  l2_edit_type:8;
};
typedef struct sys_nh_info_wlan_tunnel_s sys_nh_info_wlan_tunnel_t;

struct sys_nh_info_trill_s
{
    sys_nh_info_com_hdr_t hdr;
    sys_nh_info_bind_t* bind_data;

    uint32 gport;
    uint32 dsl3edit_offset;
    uint32 l2_edit_ptr;

    uint32 ingress_nickname:16;
    uint32 egress_nickname:16;
    uint32 l3ifid:16;
    uint32 dest_vlan_ptr:16;
};
typedef struct sys_nh_info_trill_s sys_nh_info_trill_t;

enum sys_nh_srv6_flag_e
{
    SYS_NH_SRV6_FLAG_REROUTE        =  0x0001,
    SYS_NH_SRV6_FLAG_ENCAP          =  0x0002,
    SYS_NH_SRV6_FLAG_VLAN_EDIT      =  0x0004,
    SYS_NH_SRV6_FLAG_HAVE_IPSA     =  0x0008,
    SYS_NH_SRV6_FLAG_LOOP_NH     =  0x0010,
    SYS_NH_SRV6_FLAG_SRH_IS_LDP  = 0x0020,
    SYS_NH_SRV6_FLAG_SRH_REPLACE_IPDA = 0x0040,

    SYS_NH_SRV6_FLAG_MAX
};
typedef enum sys_nh_srv6_flag_e sys_nh_srv6_flag_t;

struct sys_nh_info_srv6_s
{
    sys_nh_info_com_hdr_t hdr;
    sys_nh_info_bind_t* bind_data;

    uint32 gport;/*gport or aps group id*/
    uint32 srh_id;

    uint32 dsl3edit_offset:16;
    uint32 outer_l2_edit_offset:16;

    uint32 l3ifid:13;
    uint32 svlan_edit_type:3;
    uint32 dest_logic_port:16;

    uint32 flag:16;           /* sys_nh_srv6_flag_t */
    uint32 service_id:16;

    uint32 srv6_type:4;
    uint32 ipsa_index:8;
    uint32 cvlan_edit_type : 3;
    uint32 aps_xcon_met    : 1;
    uint32 replace_last    : 1; /* 1: support binding srh with 2 sid at most;
                                   0: support binding srh with 3 sid at most; */
    uint32 ecmp_if_id     : 13;
    uint32 rsv             : 2;
    uint32 fp_id;
    uint32 met_offset;
};
typedef struct sys_nh_info_srv6_s sys_nh_info_srv6_t;

struct sys_nh_info_ol_vni_s
{
    sys_nh_info_com_hdr_t hdr;
    uint32 inner_l2_edit_offset;
    uint32 ldp;
    uint32 cvlan_edit_type : 3;
    uint32 svlan_edit_type : 3;
	uint32 rsv             : 26;
};
typedef struct sys_nh_info_ol_vni_s sys_nh_info_ol_vni_t;


typedef uint32 (* updatenh_fn ) (uint8 lchip, void* arp_info, uint32 nh_id);

typedef int32 (* p_sys_nh_create_cb_t)(uint8 lchip, sys_nh_param_com_t* p_com_nh_para, \
                                       sys_nh_info_com_t* p_com_db);
typedef int32 (* p_sys_nh_delete_cb_t)(uint8 lchip, sys_nh_info_com_t* p_data, \
                                       sys_nh_param_com_t* p_com_nh_para);
typedef int32 (* p_sys_nh_update_cb_t)(uint8 lchip, sys_nh_info_com_t* p_data, \
                                       sys_nh_param_com_t* p_com_nh_para);
typedef int32 (* p_sys_nh_get_cb_t)(uint8 lchip, sys_nh_info_com_t* p_data, \
                                       void* p_nh_para);
struct sys_nh_ip_tunnel_sa_v4_node_s
{
    uint32  count;
    ip_addr_t ipv4;
};
typedef struct sys_nh_ip_tunnel_sa_v4_node_s sys_nh_ip_tunnel_sa_v4_node_t;

struct sys_nh_ip_tunnel_sa_v6_node_s
{
    uint32  count;
    ipv6_addr_t ipv6;
};
typedef struct sys_nh_ip_tunnel_sa_v6_node_s sys_nh_ip_tunnel_sa_v6_node_t;

struct sys_dsl2edit_vlan_edit_s
{
    DsOfEditVlanActionProfile_m data;
    uint8 profile_id;
    uint8 rsv2[3];

};
typedef struct sys_dsl2edit_vlan_edit_s sys_dsl2edit_vlan_edit_t;

struct sys_nh_mcast_traverse_s
{
    void*   user_data;
    ctc_nh_mcast_traverse_fn fn;
    uint8   lchip;
};
typedef struct sys_nh_mcast_traverse_s sys_nh_mcast_traverse_t;
#define SYS_NH_FP_DATA_NUM 16 /*sizeof ds*/
struct sys_nh_fp_prof_s
{
    uint8 type;
    uint32 data[SYS_NH_FP_DATA_NUM];
    uint16  profile_id;
};
typedef struct sys_nh_fp_prof_s sys_nh_fp_prof_t;

#define SYS_NH_FP_INST_NORMAL   0   /*normal*/
#define SYS_NH_FP_INST_PAIR     1   /*merge 2 2X to 4X*/
#define SYS_NH_FP_INST_PAIR_EXT 2   /*AT, merge 2 4X to 8X*/

struct sys_nh_fp_db_s
{
    uint32 fp_id;
    uint32 l3_edit_ptr;
    uint32 pair_edit_ptr;
    uint8  alloc_en:1;
    uint8  fp2:1;
    uint8  ext_mode:2;
    uint8  is_internal:1;
    uint8  rsv:3;
    sys_nh_fp_prof_t* p_alu_prof;
    sys_nh_fp_prof_t* p_data_prof;
    sys_nh_fp_prof_t* p_l3chksum_prof;
    sys_nh_fp_prof_t* p_l4chksum_prof;
};
typedef struct sys_nh_fp_db_s sys_nh_fp_db_t;

struct sys_usw_nh_master_s
{
    p_sys_nh_create_cb_t callbacks_nh_create[SYS_NH_TYPE_MAX];
    p_sys_nh_delete_cb_t callbacks_nh_delete[SYS_NH_TYPE_MAX];
    p_sys_nh_update_cb_t callbacks_nh_update[SYS_NH_TYPE_MAX];
    p_sys_nh_get_cb_t callbacks_nh_get[SYS_NH_TYPE_MAX];
    uint32            max_external_nhid;
    uint16            max_tunnel_id;
    uint16            max_srh_id;
    uint32*           ipmc_dsnh_offset;
    uint32*           pon_ipmc_dsnh_offset;
    uint16            ecmp_if_resolved_l2edit;
    uint16            srv6_resolved_l2edit;
    uint16            reflective_resolved_dsfwd_offset;
    uint16            reroute_dsfwd_offset;

    ctc_hash_t*       nhid_hash;
    ctc_hash_t*       nhid_ext_hash; /*sys_nh_info_ext_t*/
    ctc_vector_t*     tunnel_id_vec;
    ctc_vector_t*     mcast_group_vec;
    ctc_hash_t*       arp_id_hash;
    ctc_hash_t*       srh_id_hash;/*TMM*/
    ctc_hash_t*       ol_tunnel_hash; /*TMM*/
    ctc_hash_t*       nh_offset_hash;/*TM*/

    uint8             fp_opf_type;   /*TMM*/
    uint8             nsh_opf_type; /*AT*/
    ctc_spool_t*      p_fp_spool; /*TMM*/
    ctc_hash_t*       fp_id_hash; /*TMM*/
    ctc_hash_t*       nsh; /*AT*/
    ctc_spool_t*      nsh_ch_spool; /*AT*/

    ctc_spool_t*      p_edit_spool;
    ctc_spool_t*      p_l2edit_vprof;

    ctc_slist_t*      eloop_list;
    ctc_slist_t*      repli_offset_list;

    sys_nh_offset_attr_t sys_nh_resolved_offset[SYS_NH_RES_OFFSET_TYPE_MAX];
    sys_nh_table_entry_info_t nh_table_info_array[SYS_NH_ENTRY_TYPE_MAX];

    uint32            fatal_excp_base;
    uint32            max_glb_nh_offset;
    uint32            max_glb_met_offset;
    uint32*           p_occupid_nh_offset_bmp;       /*Occupid global DsNexthop  offset bitmap, */
    uint32*           p_occupid_met_offset_bmp;      /*Occupid global DsMET  offset bitmap, */

    uint8             ldp_mac_profile_en;
    uint8             ipmc_logic_replication;
    uint8             pkt_nh_edit_mode;            /*0: ingress edit, 1: user define,  2: misc edit,  */
    uint8             bind_ldp;          /*TM vxlan tunnel bind logic port*/
    uint8             h_ecmp_en;   /*TMM hierarchical ecmp enable*/
    uint16            cw_ref_cnt[SYS_NH_CW_NUM];

    uint16            max_ecmp;                    /**<  the maximum ECMP paths allowed for a route */
    uint16            max_ecmp_group_num;

    uint16            cur_ecmp_cnt;
    uint8             reflective_brg_en; /*default is 0, check the source and dest port in mcast replication phase, otherwise check in EPE*/
    uint16            rspan_vlan_id;                /**<rsapn vlan id, TBD, Remove*/
    uint32            nhid_used_cnt[SYS_NH_TYPE_MAX];
    uint32            nhtbl_used_cnt[SYS_NH_ENTRY_TYPE_MAX];


    uint8             nh_opf_type;
    uint8             ecmp_group_opf_type;
    uint8             ecmp_member_opf_type;
    uint8             met_mode;      /**<indicate first met use 6w or 3w, 0:3w, 1:6w. For AT, 0:1X, 1:2X, 2:4X*/

    uint32            internal_nexthop_base;
    uint32            rsv_iloop_nh;/* TMM, only for dot1ae p2mp and cloudsec, iloop to input port*/
    void *            ipsa[MAX_CTC_IP_VER];

	/*Stats share with cid and bpe ecid*/
    uint8             cid_use_4w;   /**<global ctl cid use 4w or 8w, if using 4w, nexthop stats function cannot used, default using 4w mode*/
    uint8             bpe_en;       /**<global ctl bpe use ,if using 4w, nexthop stats function cannot used, default using stats mode*/
    uint8             bpe_mc_en;

    uint8             vxlan_opf_type_inner_fid;
    uint8               bridge_inner_mode;

    uint32            overlay_ovi_num;
    uint32            xlate_nh_offset;
    uint32            mpls_edit_offset;    /* for xgpon reserved*/
    uint16            gem_port_edit_num;   /* for xgpon hybrid mode, when ctc_pon_global_cfg_t.mode is 2, one DsEdit contain 8 logicport*/
    uint16            gem_port_edit_base;  /* for xgpon hybrid mode,, when ctc_pon_global_cfg_t.mode is 2*/
    uint32            pon_mc_dsnh[SYS_NH_PON_MC_DSNH_NUM];
    ctc_hash_t*       vxlan_vni_hash;      /* used to record vn_id and fid map */
    uint32            internal_nh_used_num;
    uint16            udf_profile_ref_cnt[8];
    uint32            udf_profile_bitmap;
    uint16            udf_ether_type[8];
    uint32            efd_nh_id;          /* efd global redirect nexthop id*/
    uint32            outer_l2_ptr;/*TMM, for misc nexthop mpls replace*/
    uint32            outer_l2_ptr_ref;/*TMM*/

    uint32            rsv_l2edit_ptr;          /* reserve l2edit ptr for ipmc member */
    uint32            rsv_l3edit_for_nsh;/*AT*/
    uint16            rsv_l3edit_for_igs_edit; /*AT*/
    uint16            rsv_xedit_for_igs_edit;  /*AT*/
    uint32            rsv_nh_ptr;             /* reserve nexthop ptr for ipuc loop in replace mode */
    uint8             vxlan_mode;             /* 0:compatible mode, 1: decoupling mode,2:complete decoupling mode*/
    uint8             hecmp_mem_num;
    uint16            db_size[SYS_NH_TYPE_MAX];
    uint8             rewrite_type[SYS_NH_ENTRY_TYPE_MAX];
    uint8             met_ext_mode;/*AT, SYS_MET_MODE_NORMAL: normal mode; SYS_MET_MODE_EXT: ext mode; */
    uint32            nh_mapper_num;/*AT, DsNextHopIdMapPointe, no need save to wb db*/
    uint32            nh_mapper_base;
    uint16            ecmp_drop_mem_base[2];/*0: underlay ecmp, 1: hecmp*/

    uint8             mpls_spme_dis;
    sys_nh_vxlan_hw_profile_t*      vxlan_edit_profile;
    uint32            nsh_edit_num;
    uint32            nsh_total_num;/*scl totol num*/
    int32            ecmp_spray_ref;
};
typedef struct sys_usw_nh_master_s sys_usw_nh_master_t;

struct sys_nh_vni_mapping_key_s
{
    uint32 vn_id;

    uint16 fid;
    uint16 ref_cnt;
};
typedef struct sys_nh_vni_mapping_key_s sys_nh_vni_mapping_key_t;

struct sys_nh_param_aps_s
{
    sys_nh_param_hdr_t hdr;
    ctc_nh_aps_param_t* p_aps_param;
};
typedef struct sys_nh_param_aps_s sys_nh_param_aps_t;

struct sys_nh_offset_s/*for TM*/
{
    uint32 nh_offset;
    uint32 ref_cnt;
};
typedef struct sys_nh_offset_s sys_nh_offset_t;

struct sys_nh_mcast_dsmet_io_s
{
    sys_nh_param_mcast_member_t* p_mem_param;
    uint32 met_offset;
    uint32 next_met_offset;
    uint32 dsnh_offset;
    uint8 use_pbm;
    sys_nh_mcast_meminfo_t* p_next_mem;
};
typedef struct sys_nh_mcast_dsmet_io_s sys_nh_mcast_dsmet_io_t;

struct sys_nh_nsh_sp_ch_s
{
    uint8  ch[CTC_NH_NSH_CH_LEN];
    uint8  ch_len;
    uint32 calc_key_len[0];
    ctc_spool_index_t index;
};
typedef struct sys_nh_nsh_sp_ch_s sys_nh_nsh_sp_ch_t;

struct sys_nh_db_nsh_s
{
    uint16 nsh_id;
    uint16 edit_offset;
    sys_nh_nsh_sp_ch_t* ch;
};
typedef struct sys_nh_db_nsh_s sys_nh_db_nsh_t;

#define SYS_NH_CREAT_LOCK(mutex_type)                   \
    do                                                  \
    {                                                   \
        sal_mutex_create(&mutex_type);                   \
        if (NULL == mutex_type){                         \
            CTC_ERROR_RETURN(CTC_E_NO_MEMORY); }  \
    } while (0)

#define SYS_NH_BRGUC_LOCK \
    if(p_usw_nh_api_master[lchip]->brguc_info.brguc_mutex) sal_mutex_lock(p_usw_nh_api_master[lchip]->brguc_info.brguc_mutex)

#define SYS_NH_BRGUC_UNLOCK \
    if(p_usw_nh_api_master[lchip]->brguc_info.brguc_mutex) sal_mutex_unlock(p_usw_nh_api_master[lchip]->brguc_info.brguc_mutex)

#define SYS_NH_LOCK \
    if(p_usw_nh_api_master[lchip]->p_mutex) sal_mutex_lock(p_usw_nh_api_master[lchip]->p_mutex)

#define SYS_NH_UNLOCK \
    if(p_usw_nh_api_master[lchip]->p_mutex) sal_mutex_unlock(p_usw_nh_api_master[lchip]->p_mutex)

#define SYS_NH_DESTROY_LOCK(mutex_type) \
    if(mutex_type) sal_mutex_destroy(mutex_type)

#define SYS_NH_EDIT_MODE()   g_usw_nh_master[lchip]->pkt_nh_edit_mode

#define SYS_NH_DBG_OUT(level, FMT, ...)                          \
    do                                                     \
    {                                                      \
        CTC_DEBUG_OUT(nexthop, nexthop, NH_SYS, level, FMT, ##__VA_ARGS__);  \
    } while (0)

extern sys_usw_nh_master_t* g_usw_nh_master[CTC_MAX_LOCAL_CHIP_NUM_PP];

extern int32
sys_usw_nh_init(uint8 lchip, ctc_nh_global_cfg_t* nh_cfg);

extern int32
sys_usw_nh_mpls_add_cw(uint8 lchip, uint32 cw, uint8* cw_index,bool is_add);

extern int32
sys_usw_nh_add_mcast_db(uint8 lchip, uint32 group_id, void* data);

extern int32
sys_usw_nh_del_mcast_db(uint8 lchip, uint32 group_id);

extern int32
sys_usw_nh_traverse_nh_db(uint8 lchip, hash_traversal_fn fn, void* data);

extern int32
sys_usw_nh_write_entry_dsnh4w(uint8 lchip, sys_nh_param_dsnh_t* p_dsnh_param);
extern int32
sys_usw_nh_write_entry_dsnh8w(uint8 lchip, sys_nh_param_dsnh_t* p_dsnh_param);

extern int32
sys_usw_nh_write_entry_dsfwd(uint8 lchip, sys_nh_param_dsfwd_t* p_dsfwd_param);

extern int32
sys_usw_nh_check_max_glb_met_offset(uint8 lchip, uint32 offset);

extern int32
sys_usw_nh_check_max_glb_nh_offset(uint8 lchip, uint32 offset);

extern int32
sys_usw_nh_get_max_glb_nh_offset(uint8 lchip, uint32* offset);

extern int32
_sys_usw_nh_set_glb_met_offset(uint8 lchip, uint32 start_offset, uint32 entry_num, bool is_set);

extern int32
sys_usw_nh_set_glb_nh_offset(uint8 lchip, uint32 start_offset, uint32 entry_num, bool is_set);
extern int32
_sys_usw_nh_check_glb_met_offset(uint8 lchip, uint32 start_offset, uint32 entry_num,
                                      bool should_not_inuse);
extern int32
sys_usw_nh_check_glb_nh_offset(uint8 lchip, uint32 start_offset, uint32 entry_num,
                                     bool should_not_inuse);
extern int32
sys_usw_nh_get_resolved_offset(uint8 lchip, sys_usw_nh_res_offset_type_t type,
                                     uint32* p_offset);
extern int32
_sys_usw_nh_get_nhinfo(uint8 lchip, uint32 nhid, sys_nh_info_dsnh_t* p_nhinfo);
extern int32
_sys_usw_nh_get_reason_nhinfo(uint8 lchip, sys_cpu_reason_dest_info_t* p_dest_info, uint16 reason_id, uint32* nexthop_ptr,uint8* dsnh_8w);
extern int32
sys_usw_nh_get_ol_tunnel_info_by_ldp(uint8 lchip, uint16 logic_dest_port, sys_nh_info_com_t** pp_nhinfo);
extern int32
sys_usw_nh_get_ipmc_dsnh_offset(uint8 lchip, uint16 l3ifid, uint32 logic_port, uint8 mtu_no_chk, uint32* p_dsnh_offset);
extern int32
sys_usw_nh_get_nhinfo_by_nhid(uint8 lchip, uint32 nhid, sys_nh_info_com_t** pp_nhinfo);
extern int32
sys_usw_nh_get_nhinfo_ext_by_nhid(uint8 lchip, uint32 nhid, sys_nh_info_ext_t** pp_nhinfo, uint8 with_alloc);
extern int32
sys_usw_nh_free_nhinfo_ext_by_nhid(uint8 lchip, uint32 nhid);
extern int32
sys_usw_nh_get_mirror_info_by_nhid(uint8 lchip, uint32 nhid, uint32* dsnh_offset, uint32* gport, bool enable);
extern int32
sys_usw_nh_global_dync_entry_set_default(uint8 lchip, uint32 min_offset, uint32 max_offset);
extern int32
sys_usw_nh_offset_alloc(uint8 lchip, sys_nh_entry_table_type_t entry_type, uint32 entry_num, uint32* p_offset);
extern int32
sys_usw_nh_offset_alloc_with_multiple(uint8 lchip, sys_nh_entry_table_type_t entry_type,
                                            uint32 entry_num, uint16 multi, uint32* p_offset);
extern int32
sys_usw_nh_offset_alloc_with_direction(uint8 lchip, sys_nh_entry_table_type_t entry_type,
                              uint32 entry_num, uint8 reverse, uint32* p_offset);
extern int32
sys_usw_nh_reverse_offset_alloc(uint8 lchip, sys_nh_entry_table_type_t entry_type,
                                      uint32 entry_num, uint32* p_offset);
extern int32
sys_usw_nh_reverse_offset_alloc_with_multiple(uint8 lchip, sys_nh_entry_table_type_t entry_type,
                                                    uint32 entry_num, uint16 multi, uint32* p_offset);
extern int32
sys_usw_nh_offset_free(uint8 lchip, sys_nh_entry_table_type_t entry_type,
                             uint32 entry_num, uint32 offset);
extern int32
sys_usw_nh_copy_nh_entry_flags(uint8 lchip, sys_nh_info_com_hdr_t* p_old_hdr,sys_nh_info_com_hdr_t *p_new_hdr);
extern int32
sys_usw_nh_copy_nh_entry_flags2(uint8 lchip, uint32 flags,sys_nh_info_com_hdr_t *p_new_hdr);
extern int32
sys_usw_nh_create_brguc_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                 sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_brguc_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);

extern int32
sys_usw_nh_update_brguc_cb(uint8 lchip, sys_nh_info_com_t* p_com_db,
                                  sys_nh_param_com_t* p_com_nh_para);
extern int32
sys_usw_nh_create_mcast_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                 sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_mcast_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_update_mcast_cb(uint8 lchip, sys_nh_info_com_t* p_nh_info,
                                 sys_nh_param_com_t* p_para /*Member info*/);
extern int32
sys_usw_nh_create_ipuc_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_ipuc_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_update_ipuc_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db,
                                sys_nh_param_com_t* p_para);

extern int32
sys_usw_nh_create_special_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                   sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_special_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_com_nh_para);

extern int32
sys_usw_nh_update_ecmp_member(uint8 lchip, uint32 nhid, uint8 change_type, sys_nh_ref_list_node_t* ecmp_list);

extern int32
sys_usw_nh_create_ecmp_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para, sys_nh_info_com_t* p_com_db);

extern int32
sys_usw_nh_delete_ecmp_cb(uint8 lchip, sys_nh_info_com_t* p_com_db, sys_nh_param_com_t* p_com_nh_param);

extern int32
sys_usw_nh_update_ecmp_cb(uint8 lchip, sys_nh_info_com_t* p_ecmp_info, sys_nh_param_com_t* p_ecmp_param);

extern int32
_sys_usw_nh_get_max_ecmp(uint8 lchip, uint16* max_ecmp);

extern uint32
sys_usw_nh_get_arp_num(uint8 lchip);

extern int32
sys_usw_nh_add_l2edit(uint8 lchip, sys_dsl2edit_eth_t* p_dsl2edit_eth, uint8 edit_type, uint32* p_offset);
extern int32
sys_usw_nh_remove_l2edit(uint8 lchip, uint8 edit_type, uint32 offset);

extern int32
sys_usw_nh_lkup_mpls_tunnel(uint8 lchip, uint16 tunnel_id, sys_nh_db_mpls_tunnel_t** pp_mpls_tunnel);

int32
sys_usw_nh_add_mpls_tunnel(uint8 lchip, uint16 tunnel_id, sys_nh_db_mpls_tunnel_t* p_mpls_tunnel);
int32
sys_usw_nh_remove_mpls_tunnel(uint8 lchip, uint16 tunnel_id);
extern int32
sys_usw_nh_create_mpls_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_mpls_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_update_mpls_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db,
                                sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_create_iloop_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                 sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_iloop_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_com_nh_para);
extern int32
sys_usw_nh_update_iloop_cb(uint8 lchip, sys_nh_info_com_t* p_iloop_info, sys_nh_param_com_t* p_iloop_param);

extern int32
sys_usw_nh_create_rspan_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                 sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_rspan_cb(uint8 lchip, sys_nh_info_com_t* p_com_db, sys_nh_param_com_t* p_com_nh_para);

extern int32
sys_usw_nh_create_misc_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para, sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_misc_cb(uint8 lchip, sys_nh_info_com_t* p_flex_info, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_update_misc_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db,
                                sys_nh_param_com_t* p_para);

extern int32
sys_usw_nh_misc_init(uint8 lchip);

extern int32
sys_usw_nh_api_create(uint8 lchip, sys_nh_param_com_t* p_nh_com_para);
extern int32
sys_usw_nh_api_delete(uint8 lchip, uint32 nhid, sys_usw_nh_type_t nhid_type);
extern int32
sys_usw_nh_api_update(uint8 lchip, uint32 nhid, sys_nh_param_com_t* p_nh_com_para);
extern int32
sys_usw_nh_api_init(uint8 lchip, ctc_nh_global_cfg_t* nh_cfg);

extern int32
sys_usw_nh_get_entry_dsfwd(uint8 lchip, uint32 dsfwd_offset, void* p_dsfwd, uint8 is_dsfwd1);

extern int32
sys_usw_nh_update_entry_dsfwd(uint8 lchip, sys_nh_update_dsfwd_t* p_update_param);

extern int32
sys_usw_nh_add_stats_action(uint8 lchip, uint32 nhid, uint16 vrfid);

extern int32
sys_usw_nh_del_stats_action(uint8 lchip, uint32 nhid);

extern int32
sys_usw_nh_reset_stats_result(uint8 lchip, ctc_nh_stats_info_t* stats_info);

extern int32
sys_usw_nh_create_ip_tunnel_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                     sys_nh_info_com_t* p_com_db);

extern int32
sys_usw_nh_delete_ip_tunnel_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_com_nh_para);

extern int32
sys_usw_nh_update_ip_tunnel_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db,
                                     sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_ip_tunnel_update_dot1ae(uint8 lchip, void* param);

extern int32
sys_usw_nh_create_wlan_tunnel_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para,
                                     sys_nh_info_com_t* p_com_db);

extern int32
sys_usw_nh_delete_wlan_tunnel_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);

extern int32
sys_usw_nh_update_wlan_tunnel_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db,
                                     sys_nh_param_com_t* p_para);

extern int32
sys_usw_nh_ip_tunnel_init(uint8 lchip);

extern int32
sys_usw_nh_create_trill_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para, sys_nh_info_com_t* p_com_db);

extern int32
sys_usw_nh_delete_trill_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);

extern int32
sys_usw_nh_update_trill_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_create_srv6_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para, sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_srv6_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_update_srv6_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_get_srv6_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, void* p_para);
extern int32
sys_usw_nh_create_ol_vni_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para, sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_ol_vni_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_com_nh_para);
extern int32
sys_usw_nh_update_ol_vni_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, sys_nh_param_com_t* p_com_nh_para);
extern int32
sys_usw_nh_create_overlay_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_para, sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_delete_overlay_cb(uint8 lchip, sys_nh_info_com_t* p_data, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_update_overlay_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db,  sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_get_overlay_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, void* p_para);
extern int32
sys_usw_nh_offset_alloc_from_position(uint8 lchip, sys_nh_entry_table_type_t entry_type,uint32 entry_num, uint32 start_offset);
extern sys_nh_db_arp_t*
sys_usw_nh_lkup_arp_id(uint8 lchip, uint32 arp_id);

extern int32
sys_usw_nh_add_arp_id(uint8 lchip, sys_nh_db_arp_t* p_arp);

extern int32
sys_usw_nh_remove_arp_id(uint8 lchip, sys_nh_db_arp_t* p_arp);

extern int32
sys_usw_nh_write_entry_arp(uint8 lchip, sys_nh_db_arp_t* p_ds_arp);

extern int32
sys_usw_nh_bind_arp_cb(uint8 lchip, sys_nh_info_arp_param_t* p_arp_parm, uint32 arp_id);
extern int32
sys_usw_nh_unbind_arp_cb(uint8 lchip, uint32 arp_id, uint8 use_cb, void* node);

extern int32
sys_usw_nh_get_arp_oif(uint8 lchip, uint32 arp_id, ctc_nh_oif_info_t *p_oif, uint8* p_mac, uint8* is_drop, uint16* l3if_id);
extern int32
sys_usw_nh_deinit(uint8 lchip);
extern int32
sys_usw_nh_add_l3edit_tunnel(uint8 lchip, void* p_dsl3edit, uint8 edit_type, uint32* p_offset);
extern int32
sys_usw_nh_remove_l3edit_tunnel(uint8 lchip, uint8 edit_type, uint32 offset);
extern int32
sys_usw_nh_swap_nexthop_offset(uint8 lchip, uint32 nhid, uint32 nhid2);
extern int32
sys_usw_nh_add_loopback_l2edit(uint8 lchip, uint32 nhid, uint8 lb_with_ldp, uint8 is_l2edit, uint32* p_edit_ptr);
extern int32
sys_usw_nh_remove_loopback_l2edit(uint8 lchip, uint32 nhid, uint8 is_l2edit);
extern int32
sys_usw_nh_get_loopback_l2edit(uint8 lchip, uint32  edit_ptr,uint32 *p_nhid, uint8 is_l2edit);
extern int32
sys_usw_nh_set_bpe_en(uint8 lchip, bool enable);
extern int32
_sys_usw_brguc_nh_create_by_type(uint8 lchip, uint32 gport, sys_nh_param_brguc_sub_type_t nh_type);
extern int32
_sys_usw_misc_nh_create(uint8 lchip, uint32 nhid, sys_usw_nh_type_t nh_param_type);
extern int32
_sys_usw_nh_remove_nexthop_mac(uint8 lchip, uint32 arp_id);
extern int32
_sys_usw_nh_update_nexthop_mac(uint8 lchip, uint32 arp_id, ctc_nh_nexthop_mac_param_t* p_new_param);
extern int32
_sys_usw_nh_add_nexthop_mac(uint8 lchip, uint32 arp_id, ctc_nh_nexthop_mac_param_t* p_param);
extern int32
_sys_usw_nh_write_entry_dsfwd(uint8 lchip, sys_nh_param_dsfwd_t* p_dsfwd_param);
extern int32
sys_usw_nh_get_nhinfo_by_nhid(uint8 lchip, uint32 nhid, sys_nh_info_com_t** pp_nhinfo);

extern int32
_sys_usw_nh_dsnh_init_for_bpe_transparent(uint8 lchip, sys_nh_offset_attr_t* p_offset_attr);
extern int32
_sys_usw_nh_vxlan_vni_init(uint8 lchip);

extern int32
sys_usw_nh_update_loopback_l2edit(uint8 lchip, uint32 nhid, uint8 is_l2edit);

extern int32
sys_usw_nh_merge_dsfwd_disable(uint8 lchip, uint32 nhid, uint8 fearute);
extern int32
_sys_usw_nh_get_resolved_offset(uint8 lchip, sys_usw_nh_res_offset_type_t type, uint32* p_offset);
extern int32
_sys_usw_nh_set_ecmp_failover(uint8 lchip, uint32 nhid, uint32 gport, ctc_nh_ecmp_nh_param_t* p_nh_param);
extern int32
_sys_usw_nh_get_ecmp_failover(uint8 lchip, uint32 nhid, uint32 gport, ctc_nh_ecmp_nh_param_t* p_nh_param);
extern bool
_sys_usw_nh_is_ipmc_logic_rep_enable(uint8 lchip);
extern int32
_sys_usw_nh_set_ipmc_logic_replication(uint8 lchip, uint8 enable);
extern int32
_sys_usw_nh_free_offset_by_nhinfo(uint8 lchip, sys_usw_nh_type_t nh_type, sys_nh_info_com_t* p_nhinfo);
extern int32
_sys_usw_nh_get_mcast_nh(uint8 lchip, uint32 group_id, uint32* nhid, void** pp_db);
extern int32
_sys_usw_nh_add_udf_profile(uint8 lchip, ctc_nh_udf_profile_param_t* p_edit);
extern int32
_sys_usw_nh_remove_udf_profile(uint8 lchip, uint8 profile_id);
extern int32
_sys_usw_nh_get_udf_profile(uint8 lchip, ctc_nh_udf_profile_param_t* p_edit);
extern int32
sys_usw_nh_update_ad(uint8 lchip, uint32 nhid, uint8 update_type, uint32 nh_type,sys_nh_info_dsnh_t *p_dsnh_info);
extern int32
_sys_usw_nh_update_oam_mep(uint8 lchip, sys_nh_ref_oam_node_t* p_head, uint32 arp_id, sys_nh_info_dsnh_t* p_dsnh_info);
extern int32
_sys_usw_nh_update_oam_ref_info(uint8 lchip, void* p_nhinfo, sys_nh_oam_info_t* p_oam_info, uint8 is_add);
extern int32
_sys_usw_nh_traverse_mcast(uint8 lchip, ctc_nh_mcast_traverse_fn fn, ctc_nh_mcast_traverse_t* p_data);
extern int32
sys_usw_nh_add_srh_id(uint8 lchip, uint32* srh_id, ctc_nh_srh_edit_param_t* p_nh_param);
extern int32
sys_usw_nh_remove_srh_id(uint8 lchip, uint32 srh_id);
extern int32
sys_usw_nh_update_srh_id(uint8 lchip, uint32 srh_id, ctc_nh_srh_edit_param_t* p_nh_param, sys_com_ldp_update_t* update_param);
int32
sys_usw_nh_lkup_srh_edit(uint8 lchip, uint32 srh_id, sys_nh_db_srh_t** pp_srh);
extern int32
_sys_usw_nh_update_ol_tunnel_ref_info(uint8 lchip, sys_nh_info_com_t* p_nhinfo, sys_nh_db_ol_tunnel_t* tunnel_db, uint8 is_add);
extern int32
sys_usw_nh_add_ol_tunnel(uint8 lchip, uint32 ldp, ctc_nh_ol_tunnel_t* p_ol_tunnel);
extern int32
sys_usw_nh_remove_ol_tunnel(uint8 lchip, uint32 ldp);
extern int32
sys_usw_nh_update_ol_tunnel(uint8 lchip, uint32 ldp, ctc_nh_ol_tunnel_t* p_ol_tunnel, sys_com_ldp_update_t* update_param);

extern int32
_sys_usw_nexthop_dump_db(uint8 lchip, sal_file_t p_f, ctc_global_dump_db_t* p_dump_param);
extern int32
_sys_usw_nh_set_pw_working_path(uint8 lchip, uint8 is_working, sys_nh_info_aps_t* p_nh_aps_info);
extern int32
_sys_usw_nh_add_dsfwd(uint8 lchip, sys_nh_info_com_t* p_com_db, sys_nh_param_dsfwd_t* dsfwd_param, uint8 is_dsfwd1);
extern int32
_sys_usw_nh_remove_dsfwd(uint8 lchip, sys_nh_info_com_t* p_com_db);
extern int32
_sys_usw_nh_get_nh_resource(uint8 lchip, uint32 type, uint32* used_count);
extern int32
_sys_usw_nh_decode_vlan_edit(uint8 lchip, ctc_vlan_egress_edit_info_t* p_vlan_info, void* ds_nh);
extern int32
_sys_usw_nh_decode_dsmpls(uint8 lchip, void* p_dsmpls, ctc_mpls_nh_label_param_t* push_label);
extern int32
sys_usw_nh_get_ip_tunnel_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, void* p_para);
extern int32
sys_usw_nh_get_mpls_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, void* p_para);
extern int32
sys_usw_nh_get_misc_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, void* p_para);
extern int32
sys_usw_nh_set_met_aps_en(uint8 lchip, uint32 nhid, uint8 enable);
extern int32
_sys_usw_nh_vxlan_add_vni (uint8 lchip,  uint32 vn_id, uint16* p_fid);
extern int32
sys_usw_nh_rsv_drop_ecmp_member(uint8 lchip);
extern uint8
sys_usw_nh_is_xgpon_hybrid(uint8 lchip, uint32 logic_port);
extern sys_nh_db_ol_tunnel_t*
_sys_usw_nh_lkup_tunnel(uint8 lchip, uint32 ldp);
extern int32
sys_usw_nh_update_ip_tunnel(uint8 lchip, uint32 ldp, ctc_nh_ol_tunnel_t* p_ol_tunnel, sys_com_ldp_update_t* update_param);
extern int32
sys_usw_nh_update_aps_cb(uint8 lchip, sys_nh_info_com_t* p_com_db, sys_nh_param_com_t* p_com_nh_param);
extern int32
sys_usw_nh_delete_aps_cb(uint8 lchip, sys_nh_info_com_t* p_com_db, sys_nh_param_com_t* p_para);
extern int32
sys_usw_nh_create_aps_cb(uint8 lchip, sys_nh_param_com_t* p_com_nh_param, sys_nh_info_com_t* p_com_db);
extern int32
sys_usw_nh_update_aps_by_nh(uint8 lchip, uint32 aps_nhid, uint32 mem_nhid);
extern int32
sys_usw_nh_get_aps_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, void* p_para);
extern int32
_sys_usw_nh_decode_dsmpls(uint8 lchip, void* p_dsmpls, ctc_mpls_nh_label_param_t* push_label);
extern int32
sys_usw_nh_create_tunnel_aps(uint8 lchip, uint16 tunnel_id, ctc_nh_aps_param_t* p_para);
extern int32
sys_usw_nh_update_tunnel_aps(uint8 lchip, uint16 tunnel_id, ctc_nh_aps_param_t* p_para);
extern int32
sys_usw_nh_delete_tunnel_aps(uint8 lchip, uint16 tunnel_id);

extern int32
sys_usw_nh_create_srh_aps(uint8 lchip, uint32 srh_id, ctc_nh_aps_param_t* p_para);
extern int32
sys_usw_nh_update_srh_aps(uint8 lchip, uint32 srh_id, ctc_nh_aps_param_t* p_para);
extern int32
sys_usw_nh_delete_srh_aps(uint8 lchip, uint32 srh_id);

extern int32
_sys_usw_nh_wb_restore_edit(uint8 lchip, uint8 entry_type, uint32 edit_ptr);

extern int32
sys_usw_nh_add_vxlan_edit_profile(uint8 lchip, sys_nh_vxlan_hw_profile_t* p_profile);
extern int32
sys_usw_nh_remove_vxlan_edit_profile(uint8 lchip, sys_nh_vxlan_hw_profile_t* p_profile);
extern int32
sys_usw_nh_update_offset_ref_cnt(uint8 lchip, uint32 nhid, uint32 is_add);
sys_nh_db_ol_tunnel_t*
_sys_usw_nh_lkup_tunnel(uint8 lchip, uint32 ldp);
extern int32
_sys_usw_nh_get_ol_tunnel(uint8 lchip, uint32 ldp, ctc_nh_ol_tunnel_t* p_ol_tunnel);
extern int32
sys_usw_nh_get_ol_vni(uint8 lchip, sys_nh_info_com_t* p_info, void* p_ol_vni_param);
extern int32
sys_usw_nh_ecmp_get_lb_hash_mem(uint8 lchip, uint32 ecmp_nh_id, uint16 hash_value, uint32 * p_nh_id);
extern int32
_sys_usw_nh_ip_tunnel_add_to_tunnel_db(uint8 lchip, sys_nh_info_ip_tunnel_t* p_nhdb);
extern int32
sys_usw_nh_get_ecmp_cb(uint8 lchip, sys_nh_info_com_t* p_nh_db, void* p_para);
extern int32
sys_usw_nh_set_dirty_flag(uint8 lchip, uint32 nhid, uint8 is_set);
extern int32
sys_usw_nh_ol_tunnel_set_dirty_flag(uint8 lchip, uint32 ldp, uint8 is_set);
extern int32
sys_usw_nh_check_dirty(uint8 lchip, uint32 nhid);

/*update tunnel*/
extern int32
_sys_usw_nh_srv6_update_tnl_mem(uint8 lchip, sys_nh_info_com_t* p_nhinfo, sys_nh_db_srh_t * p_tnl, uint8 is_add);
extern sys_nh_db_srh_t*
_sys_usw_nh_lkup_srh_id(uint8 lchip, uint32 srh_id);
extern int32
sys_usw_nh_map_entry_type(uint8 lchip, sys_api_nh_entry_type_t type, sys_nh_entry_table_type_t* entry_type);

extern int32
sys_usw_nh_xgpon_flooding_en(uint8 lchip, uint32 logic_port, uint8 enable);
extern int32
sys_usw_nh_get_xgpon_flooding_dsnh(uint8 lchip, uint32 logic_port, uint32* p_dsnh_offset, uint8* p_use_dsnh8w);
extern int32
sys_usw_nh_remove_mcast_all_members(uint8 lchip, uint32 nhid);
extern  void
_sys_usw_nh_map_ether_type(uint8 lchip, uint16* ether_type, uint8* profile_id, uint8 type2id);
extern int32
sys_usw_nh_replace_mcast_members(uint8 lchip, uint32 nhid, ctc_mcast_nh_param_member_t* mem_array, uint32 mem_num);
extern int32 
sys_usw_nh_arp_alloc_dsfwd(uint8 lchip, sys_nh_db_arp_t*  p_arp, uint32* p_dsfwd_offset);
#ifdef __cplusplus
}
#endif

#endif /*_SYS_USW_NEXTHOP_INTERNAL_H_*/

